pwd-it:IT資格の勉強ブログ

IT系資格の勉強に役立つ情報などを共有していきたいと思います

1行でファイル内の特定部分の出現数を計測してランキング化するコマンド

1行でファイル内の特定部分の出現数を計測してランキング化するコマンド

やりたいこと

  • csv,tsvやwebサーバ(apache,nginx)ログファイルなど特定フォーマットで書かれたファイルを...
  • 一部分(例えばカンマ区切りの3列目)を取り出して...
  • 重複を削除し、出現重複数を集計し...
  • 出現数の多い順にソートする!

これを1行のlinuxコマンド(bash)で実現したい!

WBC準決勝の侍ジャパンの打撃成績CSVを例に説明します。

スポンサードリンク

目次

結論

こんなコマンドで集計できます。

$ grep -v "#" wbc-sf.txt | cut -d, -f4 | sort | uniq -c

集計対象のファイル

このようなファイルがあるとします。
catコマンドでファイルの中身を表示

$ cat wbc-sf.txt 
#イニング,打順,選手,結果
1,1,山田哲人,死球
1,2,菊池涼介,犠打
1,3,青木宣親,内野ゴロ
1,4,筒香嘉智,外野ライナー
2,5,中田翔,三振
2,6,坂本勇人,ヒット
2,7,松田宣浩,併殺打
3,8,秋山翔吾,内野ライナー
3,9,小林誠司,ヒット
3,1,山田哲人,内野ゴロ
3,2,菊池涼介,内野ゴロ
4,3,青木宣親,内野ゴロ
4,4,筒香嘉智,四球
4,5,中田翔,外野ライナー
4,6,坂本勇人,外野ライナー
5,7,松田宣浩,内野ゴロ
5,8,秋山翔吾,外野ライナー
5,9,小林誠司,三振
6,1,山田哲人,三振
6,2,菊池涼介,ホームラン
6,3,青木宣親,四球
6,4,筒香嘉智,三振
6,5,中田翔,内野フライ
7,6,坂本勇人,内野ゴロ
7,7,松田宣浩,内野ゴロ
7,8,秋山翔吾,内野ゴロ
8,9,内川聖一,ヒット
8,1,山田哲人,犠打
8,2,菊池涼介,三振
8,3,青木宣親,四球
8,4,筒香嘉智,外野ライナー
9,5,中田翔,内野ゴロ
9,6,坂本勇人,内野ゴロ
9,7,松田宣浩,三振

ヘッダ行は不要なので、シャープ"#"を含む行を除外します

$ grep -v "#" wbc-sf.txt 
1,1,山田哲人,死球
1,2,菊池涼介,犠打
1,3,青木宣親,内野ゴロ
1,4,筒香嘉智,外野ライナー
2,5,中田翔,三振
2,6,坂本勇人,ヒット
2,7,松田宣浩,併殺打
3,8,秋山翔吾,内野ライナー
3,9,小林誠司,ヒット
3,1,山田哲人,内野ゴロ
3,2,菊池涼介,内野ゴロ
4,3,青木宣親,内野ゴロ
4,4,筒香嘉智,四球
4,5,中田翔,外野ライナー
4,6,坂本勇人,外野ライナー
5,7,松田宣浩,内野ゴロ
5,8,秋山翔吾,外野ライナー
5,9,小林誠司,三振
6,1,山田哲人,三振
6,2,菊池涼介,ホームラン
6,3,青木宣親,四球
6,4,筒香嘉智,三振
6,5,中田翔,内野フライ
7,6,坂本勇人,内野ゴロ
7,7,松田宣浩,内野ゴロ
7,8,秋山翔吾,内野ゴロ
8,9,内川聖一,ヒット
8,1,山田哲人,犠打
8,2,菊池涼介,三振
8,3,青木宣親,四球
8,4,筒香嘉智,外野ライナー
9,5,中田翔,内野ゴロ
9,6,坂本勇人,内野ゴロ
9,7,松田宣浩,三振

grepコマンド

特定文字列を含む行を抽出します。

  • vオプション:逆に、特定文字列を含まない行を抽出します

特定列(カラム)を取り出す:cutコマンド

今回は打撃結果を撮りたいので、 「カンマ区切り」で、4列目(4カラム目)を抽出します。 上で出力したcatコマンドの出力内容をパイプ"|"で次のコマンドの入力データとして渡しています。

$ grep -v "#" wbc-sf.txt | cut -d, -f4
死球
犠打
内野ゴロ
外野ライナー
三振
ヒット
併殺打
内野ライナー
ヒット
内野ゴロ
内野ゴロ
内野ゴロ
四球
外野ライナー
外野ライナー
内野ゴロ
外野ライナー
三振
三振
ホームラン
四球
三振
内野フライ
内野ゴロ
内野ゴロ
内野ゴロ
ヒット
犠打
三振
四球
外野ライナー
内野ゴロ
内野ゴロ
三振

cutコマンド

特定文字を区切り文字に指定し、必要な列を取り出します。

  • dオプション:区切り文字(デリミタ)を指定します。今回はカンマ(,)を指定しています。
  • fオプション:列(フィールド)の番号を指定します。(一番左の列が、1です)

重複を削除し、出現回数を数える:uniqコマンド

各行の重複を削除します。重複を削除するにあたって、内容がソートされていないといけません。 先ほどまでのコマンドにさらに、2つのコマンドをパイプで追加します。

$ grep -v "#" wbc-sf.txt | cut -d, -f4 | sort | uniq -c
   6 三振
   3 四球
   1 死球
   2 犠打
   3 ヒット
   1 併殺打
  10 内野ゴロ
   1 ホームラン
   1 内野フライ
   1 内野ライナー
   5 外野ライナー

sortコマンド

その名の通り、各行を並べ替え(ソート)します。

uniqコマンド

行の重複を削除します

  • cオプション:重複出現回数を数えます。

出現数の多い順に並び替える:sortコマンド

$ grep -v "#" wbc-sf.txt | cut -d, -f4 | sort | uniq -c | sort -nr
  10 内野ゴロ
   6 三振
   5 外野ライナー
   3 ヒット
   3 四球
   2 犠打
   1 内野ライナー
   1 内野フライ
   1 ホームラン
   1 併殺打
   1 死球

sortコマンド

その名の通り、各行を並べ替え(ソート)します。

  • nオプション:ソート時に文字列ではなく、数値として評価します。
  • rオプション:逆順(降順)に並べます。

完成!

$ cat wbc-sf.txt 
#イニング,打順,選手,結果
1,1,山田哲人,死球
1,2,菊池涼介,犠打
1,3,青木宣親,内野ゴロ
1,4,筒香嘉智,外野ライナー
2,5,中田翔,三振
2,6,坂本勇人,ヒット
2,7,松田宣浩,併殺打
3,8,秋山翔吾,内野ライナー
3,9,小林誠司,ヒット
3,1,山田哲人,内野ゴロ
3,2,菊池涼介,内野ゴロ
4,3,青木宣親,内野ゴロ
4,4,筒香嘉智,四球
4,5,中田翔,外野ライナー
4,6,坂本勇人,外野ライナー
5,7,松田宣浩,内野ゴロ
5,8,秋山翔吾,外野ライナー
5,9,小林誠司,三振
6,1,山田哲人,三振
6,2,菊池涼介,ホームラン
6,3,青木宣親,四球
6,4,筒香嘉智,三振
6,5,中田翔,内野フライ
7,6,坂本勇人,内野ゴロ
7,7,松田宣浩,内野ゴロ
7,8,秋山翔吾,内野ゴロ
8,9,内川聖一,ヒット
8,1,山田哲人,犠打
8,2,菊池涼介,三振
8,3,青木宣親,四球
8,4,筒香嘉智,外野ライナー
9,5,中田翔,内野ゴロ
9,6,坂本勇人,内野ゴロ
9,7,松田宣浩,三振

$ grep -v "#" wbc-sf.txt | cut -d, -f4 | sort | uniq -c | sort -nr
  10 内野ゴロ
   6 三振
   5 外野ライナー
   3 ヒット
   3 四球
   2 犠打
   1 内野ライナー
   1 内野フライ
   1 ホームラン
   1 併殺打
   1 死球

オマケ、ちなみに対戦相手のアメリカは?

$ cat wbc-sf-usa.txt 
#イニング,打順,選手,結果
1,1,キンズラー,外野フライ
1,2,A・ジョーンズ,内野フライ
1,3,イエリチ,三振
2,4,アレナド,三振
2,5,ホスマー,内野ゴロ
2,6,マカチャン,内野ゴロ
3,7,ポージー,ヒット
3,8,スタントン,内野ゴロ
3,9,クロフォード,内野ゴロ
3,1,キンズラー,内野ゴロ
4,2,A・ジョーンズ,三振
4,3,イエリチ,内野エラー
4,4,アレナド,三振
4,5,ホスマー,四球
4,6,マカチャン,ヒット
4,7,ポージー,内野フライ
5,8,スタントン,三振
5,9,クロフォード,内野ゴロ
5,1,キンズラー,外野ライナー
6,2,A・ジョーンズ,ヒット
6,3,イエリチ,内野ゴロ
6,4,アレナド,三振
7,5,ホスマー,三振
7,6,マカチャン,三振
7,7,ポージー,三振
8,8,スタントン,三振
8,9,クロフォード,ヒット
8,1,キンズラー,ツーベースヒット
8,2,A・ジョーンズ,内野ゴロ
8,3,イエリチ,三振
9,4,アレナド,三振
9,5,ホスマー,ツーベースヒット
9,6,マカチャン,内野フライ
9,7,ポージー,内野フライ

$ grep -v "#" wbc-sf-usa.txt | cut -d, -f4 | sort | uniq -c | sort -nr
  12 三振
   8 内野ゴロ
   4 内野フライ
   4 ヒット
   2 ツーベースヒット
   1 外野ライナー
   1 外野フライ
   1 内野エラー
   1 四球

スポンサードリンク