awk

 Unixにはテキストを扱うコマンドがいろいろありますが、awkもその一つです。いわゆるテキストエディタとは異なり、行単位でデータを処理します。ここまでは以前に紹介したsedとそっくりですが、sedは数字も文字として扱ったのに対して、awkは数字は数字として扱わせて集計する、といった使い方もできる分、ちょっと高級です。

 今回は、~/terminaltestに用意した、test.txtを対象として、awkの使い方を紹介します。

bash(Mac OS X 10.3のデフォルトシェル)
PowerBookG4:~ hiro$ cd terminaltest 
PowerBookG4:~/terminaltest hiro$ ls 
test.txt
PowerBookG4:~/terminaltest hiro$ cat test.txt 
A,B C,D E,F
G,H I,J K,L
tcsh(Mac OS X 10.2.xまでのデフォルトシェル)
[PowerBookG4:~] hiro% cd terminaltest 
[PowerBookG4:~/terminaltest] hiro% ls
test.txt
[PowerBookG4:~/terminaltest] hiro% cat test.txt
A,B C,D E,F
G,H I,J K,L

 基本の書式は「awk 'スクリプト' ファイル」となります。

 awkは行の中の1つあるいは複数の連続したスペースをデータの区切りと見なして、それぞれにアクセスできます。データは左から順に$1、$2、、、となります。ですから、例えば、1行目の$1は「A,B」、$2は「C,D」ということになります。単純に指定のデータを表示するprintという命令を使って1番目と3番目のデータを表示させてみましょう。

bash
PowerBookG4:~/terminaltest hiro$ awk '{print $1,$3}' test.txt
A,B E,F
G,H K,L
tcsh
[PowerBookG4:~/terminaltest] hiro% awk '{print $1,$3}' test.txt
A,B E,F
G,H K,L

 通常はスペースでデータを区切っていますが、それを変更することも可能です。その場合、-Fオプションを使います(大文字である点に注意)。この場合の書式は、「awk -F 区切り記号 'スクリプト' ファイル」となります。
 試しに、区切り記号をカンマに変えて上と同じスクリプトを実行してみましょう。

bash
PowerBookG4:~/terminaltest hiro$ awk -F , '{print $1,$3}' test.txt 
A D E
G J K
tcsh
[PowerBookG4:~/terminaltest] hiro% awk -F , '{print $1,$3}' test.txt
A D E
G J K

 確かにデータの区切り方が変わっていますね。スペースではなくカンマで区切られているため、$1がAとGになり、$3がD EとJ Kになります。

 正規表現を使うこともできます。正規表現にマッチするデータを含む行に対して、スクリプトを実行します。その場合の書式は、「awk '/正規表現/ スクリプト' ファイル」となります。今回は[I-J]として、アルファベットのIからJまでのどれかを含む行に対してスクリプトを適用します。

bash
PowerBookG4:~/terminaltest hiro$ awk '/[I-J]/ {print $1,$3}' test.txt
G,H K,L
tcsh
[PowerBookG4:~/terminaltest] hiro% awk '/[I-J]/ {print $1,$3}' test.txt
G,H K,L

 スクリプトをファイルに記述してそれを読み込んで実行することもできます。その場合、-fオプションをつけてスクリプトファイルを指定します。

 実験に使うスクリプトは、awkのmanページに記載されているサンプルで、echoのように入力された文字列をそのまま出力するものです。そのスクリプトの先頭に#!/usr/bin/awk -fという宣言をつけてtest.awkというファイル名で保存しました。

test.awkの内容
#!/usr/bin/awk -f
BEGIN     {    # Simulate echo(1)
        for (i = 1; i < ARGC; i++) printf "%s ", ARGV[i]
        printf "\n"
        exit }
bash
PowerBookG4:~/terminaltest hiro$ ls
test.awk        test.txt
PowerBookG4:~/terminaltest hiro$ awk -f test.awk aaaaaaa
aaaaaaa
tcsh
[PowerBookG4:~/terminaltest] hiro% ls
test.awk        test.txt
[PowerBookG4:~/terminaltest] hiro% awk -f test.awk aaaaaaa
aaaaaaa

 結構いろいろできますね。実際、awkだけで本を書ける程高機能だそうで、一昔前のUnixではawkをいろいろと駆使していたみたいです。

 まあ、今から覚えるならawkでなくて、perlだと思います。