【コラム】
第4回は、awkによるHello Worldです。awkは、sedやPerlと同様、スクリプト言語の1つです。awkはPerlよりも軽量なので、awkでもPerlでも記述できるような処理は、awkで記述したほうが高速に動作するでしょう。
awkのHello Worldはリスト1の通りです。このように、awk文法のprintを使って、その引数に文字列を指定すれば、それがそのまま表示されます。
printでは、改行は自動的に付加されます。なお、awkスクリプトでは、プログラムをファイルから読み込むことを明示するため、-fオプションが必要です。
#!/usr/bin/awk -f ← awkスクリプトであることを指定(-fオプションが必要)
BEGIN { ← BEGINのパターンに対応するアクションを開始
print "Hello World" ← printを使って文字列を出力(改行は自動)
}
awkスクリプトは、シェルスクリプトと同様に、実行例1のようにchmodコマンドで実行属性を付ければ実行できます。
$ chmod +x awk_print ← awkスクリプトのファイルに実行属性を付ける
$ ./awk_print ← awkスクリプトを実行
Hello World ← 確かにHello Worldが表示される
$ ← シェルのプロンプトに戻る
awkは本来、標準入力(または引数指定の入力ファイル)から1行ずつ読み込み、何らかの加工を施して標準出力に出力するといった使い方が想定されています。このため、プログラムは「パターン { アクション }」の構造をしており、パターンには、正規表現や条件式などを使って、処理対象の行を指定します。パターンとしてBEGINを使うと、入力行を読む前にアクションが実行されます。したがって、Hello Worldのように入力行のないawkプログラムでは、パターンとしてBEGINのみを使うことになります。
なお、Solaris付属のawkは旧版のものであり、「BEGIN{}」しかないプログラムでも標準入力を読んでしまうとか、後述のsystem()が使えないなどの相違点があるため、SolarisではOS付属のnawkを代わりに使ってください。
awkにはprintfもあります。printfを使う場合はリスト2の通りで、printとは違って改行コード(\n)を付ける必要があります。
#!/usr/bin/awk -f
BEGIN {
printf "%s\n", "Hello World" ← printfを使って文字列を出力(改行が必要)
}
ところで、awkのprintやprintfは文法上のステートメントであって関数ではないため、「printf("Hello\n")」のように、( )を付ける必要はありません。しかし、( )を付けても、演算子の演算順序を指定するための括弧とみなされるだけなので、動作上は問題ありません。
プログラムをファイルから読むための-fオプションを付けずに、awkの引数にプログラムを記述し、コマンドラインなどから直接awkを実行することもできます。
実行例2は、前述のprintを使ったHello Worldを、コマンドラインから直接実行している例です。
$ awk 'BEGIN{print "Hello World"}' ← コマンドラインでawkを直接実行
Hello World ← 確かにHello Worldが表示される
$ ← シェルのプロンプトに戻る
printでは、文字列の最後に改行コードが自動的に出力されますが、これは実は、awkのORS(Output Record Separator)という変数にデフォルトで改行コードがセットされているからです。
そこで、リスト3のように、ORS自体に文字列を代入し、空のprintを実行することで変わったHello Worldのプログラムができます。
#!/usr/bin/awk -f
BEGIN {
ORS = "Hello World\n" ← 変数ORSに直接メッセージを代入(改行つき)
print ← 空のprintを実行
}
awkにはOSのコマンドを呼び出すsystem()関数があります。そこで、system()を使ってechoコマンドを呼び出すという方法も考えられます(リスト4)。
#!/usr/bin/awk -f
BEGIN {
system("echo 'Hello World'") ← OS上のechoコマンドを実行
}
awkに-fオプションを付けずに、スクリプトの1行目の#!の右のawkコマンドに、直接awkプログラムを記述する方法で、変わったHello Worldを作成することができます。
リスト5は、そのような1行だけのスクリプトです。#!の行はカーネルに直接解釈されることと、OSによって若干解釈に違いがあることから、awkの引数のプログラム部分にはスペースを入れてはいけません。そこで、文字列を"Hello"と"World"に分け、それぞれをprintの別引数として「,」で区切って記述します。こうすると、「,」の部分に1個のスペース(変数OFSの内容)が挿入されます。
#!/usr/bin/awk BEGIN{print"Hello","World"} ← 1行だけのawkスクリプト
リスト6は、ファイルにHello Worldを直接記述し、メッセージのある3行目だけをawkで抜き出すというものです。awkに-fオプションがないため、このファイルはプログラムではなく、awkへの入力ファイル(データ)となることに注意してください。
#!/usr/bin/awk NR==3{print} ← 3行目を抜き出すawkプログラムを1行で記述
Hello World ← ファイルの3行目にメッセージを直接記述
同じ発想で、メッセージを正規表現で抜き出すこともできます。リスト7は、正規表現で「#」以外で始まる空行以外の行を抜き出すという方式です。
#!/usr/bin/awk /^[^#]/{print} ← 正規表現でメッセージを抜き出すawkプログラム
← ここは空行
Hello World ← メッセージを直接記述
| 理研、脳・脊髄形成に必要な神経板湾曲の仕組みを解明 [20:16 5/25] |
| 京大、「慢性閉塞性肺疾患」患者の労作時呼吸困難は鍼治療が有効と実証 [20:08 5/25] |
| 120Hz SHVカメラ用イメージセンサーを使った撮像装置 - SHVフルスペック化へ [18:10 5/25] |
| 京大、視覚による物体認知は前頭前野からのトップダウン信号が重要と確認 [17:45 5/25] |
| 製品数の拡大だけでなくBCPの展開なども含めた総合力で事業の強化を図るTI [17:25 5/25] |
|
【連載】これだけは要チェック! TOEIC(R)単語帳 第108回 今回のお題は…「issue」 [20:00 5/27] キャリア |
|
TVアニメ『ペルソナ4』、新規カットを加えた再編集版を劇場でイベント上映 [20:00 5/27] ホビー |
|
[9nine]制服姿見納め? セーラー服で登場も川島海荷「4人はコスプレ」 [19:15 5/27] エンタメ |
|
「NO.6」4巻は書き下ろしドラマCD付、木乃のサイン会も [18:49 5/27] ホビー |
|
[今週の新刊]マンガ大賞3回ノミネート「アイアムアヒーロー」 カープ愛「球場ラヴァーズ」も [18:33 5/27] ホビー |
4つの診断で、自分の適性を見つめなおそう!
働くこと・挑戦し続けることへの思いを綴ったインタビュー
あなたにピッタリのアドバイスを読むことができます。
転職に必要な情報が収集できます
企業からアプローチのメッセージが届きます。