Linuxではテキストデータをパイプでコマンドに流し込み、段階的に加工していく使い方が基本です。
sort・uniq・cut・wc の4つを覚えると、ログ解析やCSV処理など日常的な作業の多くをターミナルだけで完結できるようになります。
wc:行数・単語数・バイト数を数える
wc(word count)はファイルや標準入力の行数・単語数・バイト数を表示します。
wc sample.txt
# 出力例: 10 42 256 sample.txt
# 行 単語 バイト
よく使うオプションは次の3つです。
| オプション | 意味 |
|---|---|
-l | 行数だけ表示 |
-w | 単語数だけ表示 |
-c | バイト数だけ表示 |
# ログファイルの行数(= リクエスト数)を数える
wc -l access.log
# パイプで渡すことも多い
cat access.log | grep "ERROR" | wc -l
sort:行を並び替える
sort は標準入力またはファイルの行をアルファベット順・数値順などで並び替えます。
sort fruits.txt
よく使うオプションです。
| オプション | 意味 |
|---|---|
-r | 逆順(降順)に並べる |
-n | 数値として並べる(文字列順だと “10” < “2” になるため) |
-k <N> | N番目のフィールドを基準に並べる |
-u | 重複行を取り除いて並べる(sort + uniq を一度に行う) |
# 数値として降順に並べる
sort -rn scores.txt
# スペース区切りの2列目を数値順に並べる
sort -k2 -n data.txt
uniq:連続する重複行を取り除く
uniq は連続する重複行を1行にまとめます。重複をまとめるには事前に sort しておく必要があります。
sort words.txt | uniq
| オプション | 意味 |
|---|---|
-c | 各行の出現回数を先頭に付けて表示 |
-d | 重複している行だけ表示 |
-u | 重複していない行だけ表示 |
# アクセスログから IP アドレスを取り出し、アクセス回数の多い順に表示
cut -d' ' -f1 access.log | sort | uniq -c | sort -rn | head -10
cut:列(フィールド)を抽出する
cut はテキストの各行から指定した列を切り出します。CSVやスペース区切りのデータを扱うときに便利です。
# コロン区切りの1列目を取り出す(/etc/passwd のユーザー名一覧)
cut -d':' -f1 /etc/passwd
| オプション | 意味 |
|---|---|
-d '<区切り文字>' | フィールドの区切り文字を指定(デフォルトはタブ) |
-f <N> | N番目のフィールドを取り出す |
-f <N,M> | N番目とM番目を取り出す |
-f <N-M> | N〜Mの範囲を取り出す |
-c <N-M> | N〜M文字目を切り出す(バイト位置) |
# タブ区切りCSVの1列目と3列目を取り出す
cut -f1,3 data.tsv
# カンマ区切りCSVの2〜4列目を取り出す
cut -d',' -f2-4 data.csv
4つを組み合わせる実践例
これらのコマンドはパイプで組み合わせて使うときに真価を発揮します。
例1:Webアクセスログから上位IPを集計する
# access.log の1列目(IPアドレス)を取り出し、アクセス数上位5件を表示
cut -d' ' -f1 access.log | sort | uniq -c | sort -rn | head -5
例2:重複なしのユーザー名一覧を作る
# /etc/passwd からユーザー名だけ取り出し、アルファベット順に並べる
cut -d':' -f1 /etc/passwd | sort -u
例3:数値データの統計
# 各行に数値が書かれたファイルを降順に並べて上位3件を表示
sort -rn numbers.txt | head -3
例4:特定の文字列を含む行だけ数える
grep "WARN" app.log | wc -l
練習問題
理解を確認するために、以下の問題に挑戦してみましょう。
問題 1
/etc/passwd に何行あるか(= 何ユーザー登録されているか)を数えるコマンドを書いてください。
問題 2
次の内容を持つファイル scores.txt があります。
Alice 85
Bob 92
Carol 78
Dave 92
Eve 85
このファイルを点数(2列目)の高い順に並べ替えて表示するコマンドを書いてください。
問題 3
/etc/passwd からシェル(7列目、区切り文字は :)だけを取り出し、重複を排除してアルファベット順に並べるコマンドを書いてください。
問題 4
カレントディレクトリ以下の .log ファイルをすべて結合し、ERROR という文字列を含む行の件数を数えるコマンドを書いてください。
解答
問題 1
wc -l /etc/passwd
問題 2
sort -k2 -rn scores.txt
-k2 で2列目(点数)を基準に、-rn で数値の降順に並べます。
問題 3
cut -d':' -f7 /etc/passwd | sort -u
sort -u は sort | uniq の短縮形です。
問題 4
cat *.log | grep "ERROR" | wc -l
# または find を使う場合
find . -name "*.log" -exec cat {} + | grep "ERROR" | wc -l