テキスト処理 初級

sortとuniqでテキストデータを整理する

Linuxのsortコマンドでテキストを並び替え、uniqコマンドで重複行を除去する方法を学ぶ

sortuniq はテキストデータを整理するときに欠かせないコマンドです。 ログ解析や 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)

辞書順では 102 より前に来てしまいます。数値として正しく並べるには -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

このコマンドは次の処理を順番に行っています。

  1. awk '{print $1}' — ログの1列目(IP アドレス)を抽出
  2. sort — IP アドレスを並び替え(uniq のために必要)
  3. uniq -c — 重複を除去しながら件数をカウント
  4. sort -n -r — 件数の多い順に並べ替え
  5. 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 で数値として昇順に並べます。