sort と uniq はテキストデータを整理するときに欠かせないコマンドです。
ログ解析や CSV の前処理など、日常的なシェル作業でよく組み合わせて使われます。
sort コマンドの基本
sort はファイルや標準入力の行を並び替えて出力します。
sort <ファイル名>
たとえば次の内容の fruits.txt があるとします。
banana
apple
cherry
apple
date
sort fruits.txt
apple
apple
banana
cherry
date
デフォルトはアルファベット順(辞書順)です。
逆順に並び替える(-r)
sort -r fruits.txt
date
cherry
banana
apple
apple
数値として並び替える(-n)
辞書順では 10 が 2 より前に来てしまいます。数値として正しく並べるには -n を使います。
echo -e "10\n2\n30\n5" | sort
10
2
30
5
echo -e "10\n2\n30\n5" | sort -n
2
5
10
30
特定の列を基準に並び替える(-k)
スペースやタブ区切りのファイルで、特定の列を基準にしたいときは -k を使います。
cat scores.txt
Alice 90
Bob 75
Carol 88
Dave 75
# 2列目(スコア)を数値として降順に並び替え
sort -k2 -n -r scores.txt
Alice 90
Carol 88
Bob 75
Dave 75
区切り文字を指定する(-t)
CSV などカンマ区切りのファイルでは -t で区切り文字を指定します。
cat data.csv
Alice,30,Tokyo
Bob,25,Osaka
Carol,30,Nagoya
# 2列目(年齢)を数値として並び替え
sort -t',' -k2 -n data.csv
Bob,25,Osaka
Alice,30,Tokyo
Carol,30,Nagoya
uniq コマンドの基本
uniq は 隣接する 重複行を取り除きます。
uniq <ファイル名>
cat fruits.txt
apple
apple
banana
apple
uniq fruits.txt
apple
banana
apple
最後の apple は残ることに注目してください。uniq は隣り合っていない重複は除去しません。
sort と組み合わせて完全に重複を除去する
すべての重複を取り除くには、sort で並び替えてから uniq に渡します。
sort fruits.txt | uniq
apple
banana
cherry
date
sort -u でも同じ結果が得られます。
sort -u fruits.txt
重複行だけを表示する(-d)
逆に、重複している行だけを確認したい場合は -d オプションを使います。
sort fruits.txt | uniq -d
apple
重複回数を数える(-c)
各行が何回出現するかを調べるには -c を使います。出現回数が行頭に付きます。
sort fruits.txt | uniq -c
2 apple
1 banana
1 cherry
1 date
出現頻度でランキングを作る
uniq -c の結果をさらに sort -n -r で並べると、出現頻度のランキングが作れます。
ログ解析などでよく使われるパターンです。
# アクセスログの IP アドレスをランキングする例
cat access.log | awk '{print $1}' | sort | uniq -c | sort -n -r | head -10
このコマンドは次の処理を順番に行っています。
awk '{print $1}'— ログの1列目(IP アドレス)を抽出sort— IP アドレスを並び替え(uniq のために必要)uniq -c— 重複を除去しながら件数をカウントsort -n -r— 件数の多い順に並べ替えhead -10— 上位10件だけ表示
練習問題
理解を確認するために、以下の問題に挑戦してみましょう。
次の内容の words.txt があるとします。
orange
apple
banana
orange
apple
grape
apple
問題 1
words.txt の内容をアルファベット昇順に並び替えるコマンドを書いてください。
問題 2
words.txt に含まれる単語の種類(重複を除いた一覧)を出力するコマンドを書いてください。
問題 3
words.txt の各単語が何回登場するかを、出現回数の多い順に表示するコマンドを書いてください。
問題 4
/etc/passwd から3列目(UID)を : 区切りで取り出し、数値の昇順で並べるコマンドを書いてください。
解答
問題 1
sort words.txt
問題 2
sort words.txt | uniq
# または
sort -u words.txt
問題 3
sort words.txt | uniq -c | sort -n -r
出力例:
3 apple
2 orange
1 grape
1 banana
問題 4
cut -d':' -f3 /etc/passwd | sort -n
cut -d':' -f3 で : 区切りの3列目(UID)を抽出し、sort -n で数値として昇順に並べます。