まだ sort して uniq してるの?
この記事の要点
※この記事は以下書籍の内容を参考に書いています。
書籍:「シェル芸」に効く!AWK処方箋
intro
エンジニアであれば、ログ調査でセッション一覧を出力する時など
『多数ある要素から重複を排除する』シーンは多いかと思います。
私の身の回りではsort
してuniq
している人が多いように感じますが
awk
のほうが便利で速いです。
awkとは
awk
[1]はUNIXで開発されたプログラミング言語で、テキスト処理に長けています。
awk
を使いこなせると、コマンドで出来ることがより"多く"なります(激寒)
awkの記法
awk '条件{命令}' 入力
boomkun@zenn:~$ echo "test" | awk '$0=="test"{print "ok"}'
ok
何が起きているか分かりますでしょうか?
条件記述部$0=="test"
が真であるため、命令部{print "ok"}
が実行されたのです。
簡単な説明は以上として、今回覚えておきたいawkの前提知識が以下の3つです。
前提知識1
条件記述部が真(=1)の場合に実行する。
前提知識2
$0は行全体を指す
前提知識3
配列を使える
さっそくやってみましょう。
awkでの重複排除(基礎編)
以下のようなhoge.txt
というファイルが仮にあったとします。
A A A
C C C
B B B
A A A
A B C
B B B
C C C
C B A
出てくる要素としてはAAA
,BBB
,CCC
,ABC
,CBA
の5つ。
コマンドを用いて求める場合、sort
,uniq
だと
boomkun@zenn:~$ cat hoge.txt | sort | uniq
A A A
A B C
B B B
C B A
C C C
sort
とuniq
の代わりにawk
を使うと
boomkun@zenn:~$ cat hoge.txt | awk '!a[$0]++{print}'
A A A
C C C
B B B
A B C
C B A
出てきた順にuniqされているのが分かるかと思います。
どういう理屈で重複が排除されているのか
条件記述部の!a[$0]++
の部分について深堀りしてみましょう。
a
という配列に$0
をぶち込み、返ってきた値を後置インクリメントしています。
つまり、『1度目は真、2度目以降は偽』となるため
最初に出てきた時のみ{print}
アクションがおこります。
awkでの重複排除(応用編)
今回紹介したawkの重複排除!a[$0]++
は応用も幅広くききます。
- 重複しているもののみ出力
!
を外してa[$0]++
とするだけです。
boomkun@zenn:~$ cat hoge.txt | awk 'a[$0]++{print}'
A A A
B B B
C C C
-
$x
の重複するものを出力
配列に入れるものをa[$2]
とすれば『$2
の重複するものを出力』出来るでしょう。 - 重複行がX個以上あるものだけ出力
'a[$0]++ == X'
outro
うまく説明できた気がしませんが、awkについての小ネタでした。
たまに業務につながることがあるので、シェル芸の問題を解くのは息抜きにオススメです。
なにより時系列が大事なセッション抜き出しで、『sortせずuniq』出来るのは
ログ調査などで大きな助けになるかもしれませんね。
参考書籍:「シェル芸」に効く!AWK処方箋
Discussion
出てきた順に uniq はできませんが、sort して uniq であれば
sort -u
で出来ます。うわ恥ずかしい。知りませんでした…
ありがとうございます!