Linux コマンド再入門 (cut, sort, uniq)

で。

Linux (Unix) には、コマンドラインで色々できるものが揃っているので、これ使えるか使えないかで、大きな差がでてしまうな、と最近つくづく思う。いわゆる、GNU Coreutilsというやつだ。*1
実は知らなくても生きていけるし、RubyPython 書けば適当に(それも短時間で)実現できてしまうが、知っておけばさらに簡単に実現できてしまうということは往々にしてあり、そういうわけで、最近は、データ解析とか、集計とかに役立つ Linux コマンドを再度確認するといいのではないか、と思っている。

以上前置き。

サンプルデータ

サンプルデータは、前回 つかった、TiarraTwitter ログをタブ区切りにして出力した一部を使うことにする。

2009-06-15 00:36:00     mickey24        -       こちらも.Rのanimationパッケージでクラスカル法のシミュレーション http://d.hatena.ne.jp/mickey24/20090614/1244965435
2009-06-15 00:36:00     mickey24        syou6162        しばらく前にアップできるようになってたよー.
2009-06-15 00:39:00     Makoto1987      -       手元に結局使わなかった池袋駅の振替乗車票が。
2009-06-15 00:39:00     yuzuhara        -       うーん,reducerがおかしい
2009-06-15 00:39:00     suztomo -       今日は六本木ヒルズの上のほうに図書館があるのを知った.月額9,450円.
2009-06-15 00:40:00     mickey24        -       例のおまけのアレはGIFアニメだと3.6M,MPEGだと1.5M….
2009-06-15 00:40:00     from_kyushu     -       MacPortsのkdelibs4、md5の値がおかしい?
2009-06-15 00:40:00     totte   -       2ちゃんとかで無名の人から商品disられるのとついったーで知ってる人に商品disられるのは、やっぱ色々違うよなー。善処可能なdisならいいけど、ダサいとかパクりじゃね?とかだと。
2009-06-15 00:40:00     syzfonics       -       CD取り込み終わってるし机に戻る
2009-06-15 00:42:00     imai78  -       日記も書いたし、いったん帰ろう
2009-06-15 00:44:00     cho45   -       perl で不正なUTF-8文字列とりのぞくのってどうするんだろ……
2009-06-15 00:44:00     totte   -       かといって言葉狩りはやだし。やっぱり「この映画つまらなかった」と思ったらそうPOSTしたい人もいるだろうし。(自分もしてるかもだから気をつける
2009-06-15 00:44:00     oza_x86 -       TwitterPod ga
2009-06-15 00:44:00     from_kyushu     -       メンテナにメールしようかと思ったらmaintainersの欄がnomaintainerになっとる......
2009-06-15 00:44:00     onodes  -       鯖が外部公開できない・・・
2009-06-15 00:45:00     sayakame        -       リア充は いつもじぶんのこころがきめる みつを
2009-06-15 00:45:00     replore -       なっちゃんすごい
2009-06-15 00:45:00     oza_x86 -       Now, Twitterpod was updated!  I can *twit* through it again!
2009-06-15 00:47:00     YurineMashiro   -       夜フクロウ使ってみてる。ものすごく使いやすいのは間違いないけどもうTIGしか使えないなー。
2009-06-15 00:47:00     witchmakers     -       ジャックフロスト>>>(越えられない壁)>>>モーグリ、チョコボ、スライム

の20行。
タブ区切りで、日付、ID、Reply先、メッセージ、が記録されている。

cut

cutコマンドは、各行の一部を取り出すコマンド。
その「一部」を、何単位にするかをオプションで指定できる。

オプションは、

  • -f
    • フィールド
  • -b
    • バイト
  • -c
    • 文字

となっている。

cut -f

多分一番よく使うので、-f から。
なにかを区切りとして(デフォルトでは「タブ」)一部のフィールドを取り出すことができる。例えば、日付だけを取り出したい場合は、次のようにする。(-f1)

% cut -f1 twitter_log.20.txt
2009-06-15 00:36:00
2009-06-15 00:36:00
2009-06-15 00:39:00
...(snip)

フィールドの番号は、1オリジン。


日付と発言者のみを取り出したい場合は、次のようにする。(-f1,2)

% cut -f1,2 twitter_log.20.txt 
2009-06-15 00:36:00     mickey24
2009-06-15 00:36:00     mickey24
2009-06-15 00:39:00     Makoto1987
...(snip)

日付〜Reply先を取り出したい場合は、次のようにする。(-f1-3)

% cut -f1-3 twitter_log.20.txt 
2009-06-15 00:36:00     mickey24        -
2009-06-15 00:36:00     mickey24        syou6162
2009-06-15 00:39:00     Makoto1987      -
...(snip)


日付〜発言者、内容を取り出したい場合は、会わせ技で。(-f1-2,4 or -f1,2,4)

% cut -f1-2,4 twitter_log.20.txt
2009-06-15 00:36:00     mickey24        こちらも.Rのanimationパッケージでクラスカル法のシミュレーション http://d.hatena.ne.jp/mickey24/20090614/1244965435
2009-06-15 00:36:00     mickey24        しばらく前にアップできるようになってたよー.
2009-06-15 00:39:00     Makoto1987      手元に結局使わなかった池袋駅の振替乗車票が。
...(snip)


ついでに、 -d を使って、フィールドの区切り文字を変更することができる。例えば、日付の中から時刻のみを取り出す場合。さらに、hh:mm:ss から hh:mm だけを取り出したい場合。

% cut -f1 twitter_log.20.txt | cut -d" " -f2 | cut -d":" -f1-2
00:36
00:36
00:39
...(snip)
cut -c

文字単位で切り取れる。数字の指定は、フィールドと同じように、 1 などと単体で指定することも、 1,2,3 などと列挙したり、 1-4 のように範囲を指定したりできる。
例えば、発言の頭文字だけを取り出すとか。

% cut -f4 twitter_log.20.txt | cut -c1
こ
し
手
...(snip)
cut -b

バイト単位で切り取れる。

% cut -b12-16 twitter_log.20.txt
00:36
00:36
00:39
...(snip)

マルチバイト文字が含まれなければ、 -b も -c も同じ。(マルチバイト文字を中と半端に分割しないようにするには、 -n オプションをつける)


詳しくは man cut で。

sort

標準入力をソートして標準出力する。

ソート対象のフィールドは、-k で、 区切り文字は -t で指定する。さらに、 -u でソート結果の連続する同じ値(ソート対象フィールドが)を1つにまとめたり(この場合、最初のみが出力される)、-f で case insesible に比較できる。

例えば、発言者でソートした結果を出力するには以下のようにする。デフォルトでは、-k で指定するフィールドの区切り文字が「空白文字」となっているので、 フィールドの3を指定している。

% sort -k3,3 -f twitter_log.20.txt
2009-06-15 00:44:00     cho45   -       perl で不正なUTF-8文字列とりのぞくのってどうするんだろ……
2009-06-15 00:40:00     from_kyushu     -       MacPortsのkdelibs4、md5の値がおかしい?
2009-06-15 00:44:00     from_kyushu     -       メンテナにメールしようかと思ったらmaintainersの欄がnomaintainerになっとる......
2009-06-15 00:42:00     imai78  -       日記も書いたし、いったん帰ろう
2009-06-15 00:39:00     Makoto1987      -       手元に結局使わなかった池袋駅の振替乗車票が。
2009-06-15 00:36:00     mickey24        -       こちらも.Rのanimationパッケージでクラスカル法のシミュレーション http://d.hatena.ne.jp/mickey24/20090614/1244965435
2009-06-15 00:36:00     mickey24        syou6162        しばらく前にアップできるようになってたよー.
2009-06-15 00:40:00     mickey24        -       例のおまけのアレはGIFアニメだと3.6M,MPEGだと1.5M….
2009-06-15 00:44:00     onodes  -       鯖が外部公開できない・・・
2009-06-15 00:44:00     oza_x86 -       TwitterPod ga
...(snip)


ただし、 -t¥t などとしてタブ文字を区切りに指定することもできるが、環境によってはうまく比較できないので(LC_ALL)、まあだいたい他のコマンドと組み合わせて使うことが多いとは思う。

詳しくは man sort で。

uniq

連続して同じ値が現れたときに、一つにまとめることができる。

% cut -f1 twitter_log.20.txt | uniq
2009-06-15 00:36:00
2009-06-15 00:39:00
2009-06-15 00:40:00
2009-06-15 00:42:00
2009-06-15 00:44:00
2009-06-15 00:45:00
2009-06-15 00:47:00


また、 -c でまとめた数も出力できる。例は、各時間に何回発言があったかがわかる。

% cut -f1 twitter_log.20.txt | uniq -c
   2 2009-06-15 00:36:00
   3 2009-06-15 00:39:00
   4 2009-06-15 00:40:00
   1 2009-06-15 00:42:00
   5 2009-06-15 00:44:00
   3 2009-06-15 00:45:00
   2 2009-06-15 00:47:00

詳しくは(r

パイプで組み合わせ

まぁこれまでの例でもパイプで組み合わせて色々やったけど、例えば、前回やったこと(IDごとに発言回数を出して多い順に並べる、とか)なんかは非常に簡単にできる。

% cut -f2 twitter_log.20.txt | sort | uniq -c | sort -r
   3 mickey24
   2 totte
   2 oza_x86
   2 from_kyushu
   1 yuzuhara
   1 witchmakers
   1 syzfonics
   1 suztomo
...(snip)

次回は

知っていれば当然楽だよね、の代表、sedawk について書くかなあ。つっても自分も初心者だからあまり、込み入った使い方はできないんだけども。

つか、今更入門しなくても、それ Perl でとか、色々あるとは思うんだけど、要は道具は使いようってことで、こういうときにはこういうものが使えるよね、ということを知ってるか知っていないかで、目的まで遠回りをするか近道でいけるか、ということが大きく異なると思うのです。

というわけで。

*1:ちなみに、このあたりは、LinuxUnix、Mac OSX (*BSD), Solaris とかで色々バージョンや引数が違ったりするので、詳しくは man で・・・って感じになっちゃうけど。