2014年11月17日月曜日

Unixテキスト処理コマンド集【cat, head, tail, grep, sort, join, awk】

テキスト形式のデータ処理に便利なUnixコマンドを紹介します。
Unixコマンドは無数にあるのですべてをカバーすることは出来ません。

ここではお手軽に一行で書けるコマンドを中心に扱います。多くの「ちょっとした処理」はこれらの組み合わせで行うことが出来ます。


cat

cat <オプション> <ファイル>

全文を出力する。いわずもがななコマンド。
元々ファイルをつなげる(concatenate)為に実装されたコマンドですが、主に小さいファイルのダンプの為に使われています。
有用なオプションとしては-n: 行番号を出力するというものがあります。これを使うとコンパイルエラーの出た箇所の確認などに便利です。

cat run.sh -n
     1    #!/bin/sh
     2   
     3   
     4    # arg1 = time
     5    #
     6    #
     7   
     8    cd $PBS_O_WORKDIR
     9    ./tiles$time $algname $PBS_ARRAYID $thread_number $param1 $param2 $param3 < $problem_type
    10   
ちなみにcatの語源はconcatenate(つなげる)の略形です。


head

head <オプション> <ファイル>

ファイルの先頭の10行を出力する。大きなデータファイルを確認する場合や、ファイルヘッダーのみ確認する場合に便利です。

オプション-nで任意の行数を出力することが出来ます。
例えば
head  -n 20 astar.dat
ならば先頭20行が出力されます。
head -n -20 astar.dat
とすると最後の20行以外のすべての行を出力します。
ただしheadと続くtailはUnixのディストリビューションによって若干異なるインターフェイスを持っています。中身は同じなので大きな違いはありませんが、manページを見ておく必要はあると思います。

ちなみにheadとtailで行番号を出力したい場合は
cat astar.dat -n | head -n -20
のようにすれば出来ます。この場合の行番号は元のファイルにおける行番号になります。


tail

tail <オプション> <ファイル>
ファイルの末尾の10行を出力する。headと相似形であるので説明はheadを見てください。


grep

grep [オプション] パターン [ファイル...]
grep [オプション] [-e パターン | -f ファイル] [ファイル...]
パーサとして優秀なコマンド。特にログから必要なデータをマイニングする場合によく使われます。
例えば、
grep cron /var/log/syslog
とおくとファイル/var/log/syslogの中で文字列"cron"を含む行を出力します。cronジョブのデバッグをする場合はこれを読むと原因がすぐに分かります。
このコマンドを熟知していれば「ログが多すぎて必要なデータが分からなくなってしまった」ということはありません。

オプションやトリックは様々あるのですべてを網羅することは出来ませんがいくつか基本のものを紹介します。


-c, --count
通常出力の代わりにパターンに一致した行が何行あったかを出力する。
-l, --files-with-matches
通常出力の代わりにパターンに一致した行のあるファイルの名前を出力する。

大規模なデータを扱う場合はgrepの通常出力が大きくなりすぎて扱いにくくなってしまうことがありあます。大きな詳細を扱うのではなく、より大きな傾向を見る場合に使いやすいオプションです。木ではなく森を見るためのコマンドといえるでしょう。

語源はテキストエディタedのGlobal Regular Expression Printから。


sort

sort [OPTION]... [FILE]...
ファイルの行をソートする。デフォルトだと先頭のフィールドに基づいてソートされる。
データは順番が重要になることがあります。例えばgnupotは一行ずつ読み込んで処理するシステムの一つです。plot with linesとするとデータ入力順に線を引いていきます。

デフォルトだと入力文字列を文字列としてみなしてソートする。どういうことかというと、以下のtest.txtをソートすると10が2よりも前にくるということです。
$ cat test.txt
0 zero
1 one
2 two
10 ten
 これをsortすると、
$ sort test.txt
0 zero
10 ten
1 one
2 two
2どころか1よりも手前にきてしまいます。フィールドを数字としてみなしてソートする為には-nオプションをつける必要があります。
$ sort sort.txt -n
0 zero
1 one
2 two
10 ten

join

join [OPTION]... FILE1 FILE2
二つのファイルの内部結合(inner join)を出力する。
比較データなどを1ファイルにまとめる場合などに便利です。
-aコマンドでouter joinにすることが出来る。

結合フィールドはソートされている必要があるので、前述のsortを使うことになります。sortされていない形を保つ必要がある場合はcat -nで行番号を加えることで便宜的なイテレーション番号をつけ、それに基づいてソートをするということが出来ます。


awk

awkは一行でテキスト処理を行う軽快なコマンドであると同時に表現力豊かなプログラミング言語でもあります。awkのスクリプトを書けばこれまで述べてきたコマンドをawkで実装することも出来ます。しかしながらここでは一行でかける簡単な処理に絞って説明をします。詳しい言語実装を知りたい方は下記リンクをご参照下さい。

awkの基本骨子は

1. データファイルを一行読み込む
2. パターンマッチングを行う
3. パターンにマッチした場合に処理を行う

です。例えば
awk '/error/{print $1, $2}'
とすれば"error"の文字列を含む行の1番目、2番目の語を出力するという処理になります。

パターンマッチングの部分はgrepに似ていますが、awkの方がより深入りをして細かい場合分けや出力の指定をすることが出来ます。

データのフォーマットを変えたり、複数データから平均を計算したり、gnuplotに渡すデータを作成したり、shell scriptの中で活躍できるコマンドです。 結構しっかりとした言語なので詳解な説明は下記リンクに譲ります。

*awk参考リンク

The GNU Awk User's Guide
フルドキュメント。非常に詳解なので困ったらこれを見ればいいでしょう。

AWK入門(ドットインストール)
awkの入門の為ならこちらをお勧めします。awkのしっかりとした言語であるという側面と、簡単に記述できるという側面の両方を見ることが出来ます。


0 件のコメント:

コメントを投稿