講座「文系のためのawkプログラミング入門」
今回は処理結果のデータの出力を学びます。データの出力については二つのことを考える必要があります。ひとつは出力先です。ファイルに出力するのか、コンピュータの画面に出力するのか、それともクリップボードか、などなどです。もうひとつは、出力データの形式です。これは実に様々で、改行をつけて出力するのか、改行なしで出力するのか。また数字であれば、小数点の位置を揃えて見やすくするとか、色んなやり方があります。今回はこのようなデータの出力の基本を学びます。awkでは、処理したデータを出力するときに用いる命令は、print と printf の二つがあります。従ってこの二つの命令の基本を学ぶことになります。
出力先は様々だと上で書きましたが、実はawk自体では、二つの出力先の指定しかできません。標準出力と、ファイルへの出力の二つです。print文を例にとると、スクリプトの中で
print $1 #標準出力 print $1 > file_name #ファイルへの出力
上のように、print 文の 後ろに出力するデータだけ記述して、そのあと何も書かなければ、「標準出力」になります。> や >> の記号(これをリダイレクト演算子と言う)と、その後にファイル名を書けば、ファイルへ出力します。
ちょっとややこしいのは標準出力の方です。標準出力というのは、awkのデータの吐き出し口につけた名前なのですが、ここからデータを出力する場合、そのデータを受け取る容器は、awkを起動した側で用意してやらなければなりません。標準出力は水道の蛇口のようなもので、その下にバケツなり、コップなりを置いてやる必要があります。コマンドプロンプトを使う場合、コマンドプロンプトは普通は、awkからデータを受け取って、コマンドプロンプトのウィンドウに表示するようにしています。またコマンドプロンプトでawkを起動するときに、
gawk -f "script.awk" > "result.txt"
上のような形で起動して、">" の記号のあとファイル名で出力先を指定すれば、コマンドプロンプトはawkからデータを受け取り、ファイルに流し込んでくれます。この場合、上のスクリプトの中の書き方と似ていますが、あくまでもこれは、コマンドプロンプトに対して、awkの標準出力を、"result.txt"へ流し込むように命令しています。
おーくの友だちも、この標準出力を受け取るためにいくつかのオプションを用意しています。詳しくはヘルプを見ていただくとして、Output欄で選択できるのは次のようなものです。
1 Files(new) #処理するファイルの名前に、new_ などを付け加えたファイルに出力 2 単一上書 #指定した単一のファイルに上書き 3 単一追加 #指定した単一のファイルに追加 4 Screen # おーくの友だちのウィンドウに出力 5 Clipboard # クリップボードに出力 6 Null # 指定しない(スクリプトの中で直接指定)
ここで、スクリプトの中で指定する方法について、注意しておきますと、
1) スクリプト中で指定する場合は、出力先のファイルをフルパスで指定しないといけない
2) ファイルが存在しない場合は、awkはファイルを作成するが、存在しないディレクトリの中にファイルを指定するとエラーになる。
3) ファイル名は引用符で囲み、そのときディレクトリを表す"\"記号は二つ重ねないといけない。
3番目の点について実例をしめせば次のようになります。
# script 5-1 BEGIN{ print "これは書き込みテスト" > "c:\\test\\result.txt" }
このスクリプトを実行するときは、必ず、C ドライブに test というフォルダを作ってから実行してください。Input欄はNull、 Output欄もNull にします。
# script 5-2 BEGIN{ print "二回目の書き込みテスト" >> "c:\\test\\result.txt" }
5-2も同様に実行してみて下さい。また ">>" を ">" に変えて実行してください。">"は上書き、">>" は追記します
この二つの文の違いは、まず改行をつけて出力するか、そうでないかの違いです。下の5-3 と 5-4 のスクリプトを実行すればすぐわかります。
# script 5-3 printf 文は改行を出力しない BEGIN{ printf "I am a boy." printf "You are a girl." printf "He is my brother." }
実行すると次のように出力されます。
I am a boy.You are a girl.He is my brother.
print文は改行を最後につけて出力します
# script 5-4 BEGIN{ print "I am a boy." print "You are a girl." print "He is my brother." }
実行すると次のように出力されます。
I am a boy. You are a girl. He is my brother.
printf 文でも、その最後に改行記号、"\n" をつけて出力すると、print文と同じ結果になります。
# script 5-5 printf 文で改行を出力する BEGIN{ printf "I am a boy.\n" printf "You are a girl.\n" printf "He is my brother.\n" }
実行してみて下さい、5-4 と同じ出力結果が得られます。
printf文の本来の用途は、出力の細かな制御です。これはC言語のprintf文とほぼ同じ働きをします。一般的にその使い方を書けば以下のようになります。
printf( 書式, 出力データ1, 出力データ2, 出力データ3,---)
ここで、書式は引用符で囲んだ特有の書式文字列になります。そのあとにコンマで区切って、出力したいデータを並べます。このデータは生の文字列や数値でも良いし、変数でもかまいません。簡単な例を示しましょう。
# script 5-6 BEGIN{ x = 8 y = 100 z = 10 printf("%3d\n",x) printf("%3d\n",y) printf("%3d\n",z) }
書式文字列で、%d はデータを 数として出力することを意味します。d の前に 数字をつければ(例では 3 です)その数だけ、1の位の数字の位置を後ろにずらせて印字します。 5−5のスクリプトで、3 をとって実行すれば、その効果ははっきりします。また改行するときは、書式文字列の最後に \n をいれないといけません。 もうひとつ、例を示しましょう。こんどは文字列を揃えて出力します。データを文字列として出力するときは、%s を使います。
# script 5-7 BEGIN{ x = "January" printf("%10s\n",x) x = "February" printf("%10s\n",x) x = "march" printf("%10s\n",x) }
実行してみて下さい。月の名前が、10文字の幅で後ろを揃えて出力されます。
こんどは、出力データが二つある場合の例です。
# script 5-8 BEGIN{ x = "melon" y = 1600 printf("%10s%7d円\n",x,y) x = "egg" y = 15 printf("%10s%7d円\n",x,y) x = "coffee" y = 200 printf("%10s%7d円\n",x,y) }
おーくの友だちで実行してみて下さい。きれいに揃って出力されます。 printf文のこういう使い方は、慣れないうちは少し難しく感じるかもしれませんが、慣れれば分かりやすいものです。どうしたら慣れることが出来るのか、それは常に同じです。awkはツールですから、よく使って手に馴染ませることです。上に例として掲げたスクリプトをおーくの友だちで実行して実際の動作を確認して下さい。
ここまででデータの入力、処理、出力の基本中の基本を一通り見てきました。awkがどういうプログラムであるのか、だいぶ理解されてきただろうと思います。次回からは、awkによるテキスト処理の中身について本格的に学んでいきます。
printf文の その他のサンプルを挙げておきましょう。そのまま実行すれば、それぞれの出力の違いが分かるでしょう。
# script 5-9 BEGIN{ x=97.5 printf(":%d\n",x) #整数として出力 printf(":%5d\n",x) #5桁で右詰の整数として出力 printf(":%e\n",x) #浮動小数点数(eの後の数字は10の累乗を表す) printf(":%7.2f\n",x) #浮動小数点数、7桁で小数第2位まで printf(":%6.2f\n",x) #浮動小数点数、6桁で小数第2位まで printf(":%5.2f\n",x) #浮動小数点数、5桁で小数第2位まで printf(":%4.2f\n",x) #浮動小数点数、4桁で小数第2位まで print "-------------" x=100 printf(":%o\n",x) #8進数として出力 printf(":%x\n",x) #16進数として出力 printf(":%c\n",x) #文字コードして対応するアルファベットを出力 print "-------------" x="January" printf(":%s\n",x) #そのまま文字列として出力 printf(":%10s\n",x) #右詰で10桁のスペースに出力 printf(":%-10s\n",x) #左詰で10桁のスペースに出力 printf(":%.3s\n",x) #左詰で3文字のみ出力 printf(":%10.3s\n",x) #右詰で10桁のスペースに3文字を出力 printf(":%-10.3s\n",x) #左詰で10桁のスペースに3文字を出力 }