移動先 先頭, , , 末尾 セクション, 目次.

出力を行う

もっともよく行われるアクションの一つは、入力の一部もしくは全部を出力するこ とである。単純な出力のためにprint文を使い、整形して出力するために printf文を使う。この両者はこの章で説明する。

The print Statement

print文は出力を単純に、標準的な書式で行う。カンマで区切られたリストに なっているデータを文字列とするか数値として出力するかを特定できるだけである。 出力は一つのスペースで区切られ、最後に改行が加えられる。例を挙げよう。

print item1, item2, ...

アイテムのリストは、全体を括弧でくくる事もできる。この括弧は、アイテムのいず れかが関係演算子を使った式である場合には使う必要がある。そうしないと、リダ イレクションと混同してしまう可能性があるだろう (セクション Redirecting Output of print and printfを参照).

プリントの対象となるアイテムは文字列定数や数値定数、カレントレコードのフィー ルド($1のような)、変数、式である。 print文は出力する値を完全 に計算する。二つの例外として、どのように出力するか、つまりどの位カラムを出力 するか、指数表示を使うか使わないか等を指定することはできない

print文は演算結果を出力するのに汎用的なものである。しかしながら、 二つの例外があって、どのように出力するのか、つまりどのくらいのカ ラム数で、とか指数表記を使うのか使わないのかなどということを指定できない (この例外についてはセクション Output Separatorsを参照, および セクション Controlling Numeric Output with printを参照.)。 このためにはprintf 文を使う必要がある (セクション Using printf Statements for Fancier Printingを参照)。

単に`print' とだけ書かれて何もアイテムのない`print' 文は `print $0'と同じ動作、つまりカレントレコード全体を出力する。空行を出力 するには、`print ""'として、空文字列を指定する。

固定したテキストを出力するためには、"Hello there"の様な文字列定数 を使う。ここで二重引用符を忘れた場合、そのテキストは式として扱われて、おそ らくはエラーとなるだろう。また、二つのアイテムの間にはスペースが出力される ことを覚えておいて欲しい。

ほとんどの場合、各々のprint文は一行の出力を作り出す。しかし、一行にか ぎらない。もし、アイテムの値が改行を含む文字列であった場合、改行は残りの文字 列とともに出力される。このやり方で、一つのprintで多くの行を出力するこ とができる。

Examples of print Statements

次に挙げるのは改行が埋め込まれた文字列の出力の例である (`\n'はエスケープシーケンスであり、改行を表わすものである セクション エスケープシーケンスを参照)。

$ awk 'BEGIN { print "line one\nline two\nline three" }'
-| line one
-| line two
-| line three

次の例はカレントレコードの最初の二つのフィールドを空白で区切って出力する。

$ awk '{ print $1, $2 }' inventory-shipped
-| Jan 13
-| Feb 15
-| Mar 15
...

print 文を使うときにありがちな間違いは、二つのアイテムの間に置かれるカ ンマを忘れてしまうという事である。それはスペースなしに、一つにまとまって出力 される結果となるだろう。なぜなら、二つの並んだ文字列というのはawk で は連接を行う式を意味するからだ。カンマがない例として、

$ awk '{ print $1 $2 }' inventory-shipped
-| Jan13
-| Feb15
-| Mar15
...

`inventory-shipped'にあまり馴染みのない人に対してもわかりやすい出力 をしよう。最初のヘッダ行で何を出力しているかを明確にしようとして、月ごと の量($1)と、緑のクレーの積込量($2)のテーブルにヘッダを付け 加えている。これをBEGINパターン (セクション 特殊パターンBEGINENDを参照) を使って出力の最初に一回だけ出力させている。

awk 'BEGIN {  print "Month Crates"
              print "----- ------" }
           {  print $1, $2 }' inventory-shipped

どう出力されるか予想できるだろうか? このプログラムの出力はこうなる。

Month Crates
----- ------
Jan 13
Feb 15
Mar 15
...

ヘッダとデータのテーブルがきちんと揃っていない! しかし、二つのフィールドの 間に固定長のスペースを出力するようにできる。

awk 'BEGIN { print "Month Crates"
             print "----- ------" }
           { print $1, "     ", $2 }' inventory-shipped

このカラムの揃え方は多くのカラムがあった場合に揃えるのが少々面倒になることが 想像できるだろう。二、三個のカラムのためなら単純にスペースを数えられるだろう が、これがもっと多かったりすると数え間違えやすくなる。それが printf 文が作られた理由である (セクション Using printf Statements for Fancier Printingを参照)。 その機能の一つにデータのカラムをそろえることがある。

print文やprintf文では、任意のカンマの後に 改行を置くだけで行の継続を行うことができる。 (セクション awk の文と行を参照).

Output Separators

先に述べたように、print文はカンマで区切られたアイテムのリストを含 む。出力では、各アイテムは単一のスペースで区切られる。これはただのデフォ ルトであり、常にそうであるわけではない。組込み変数のOFSに任意の文 字列をセットすることによって出力フィールドセパレータを指定すること ができる。この変数の初期値は" "であり、単一のスペースである。

print文による出力全体は出力レコードと呼ばれる。各print 文は一つのレコードを出力し、その後に出力レコードセパレータと呼ばれ る文字列を出力する。組込み変数ORSがこの文字列を特定する。ORS の初期値は"\n"という文字列である。これは改行であり、したがって、通 常は各print文は分割された行を作成する。

OFSORSといった変数に新しい値をセットすることによって、 出力フィールドや出力レコードをどのように分割するかを変更することが できる。通常これを行う場所は、入力がまだ処理されないBEGINルール (セクション 特殊パターンBEGINENDを参照) の中である。同じことを、コマンドライン上で入力ファイル名の前に変数への 代入を行うことでもできるし、`-v'オプションを使うことでもできる。 (セクション コマンドラインオプションを参照).

次の例では、各入力レコード中のセミコロンで区切られた フィールドの一番目と二番目を、各行の後ろに空行を追加して出力する。

$ awk 'BEGIN { OFS = ";"; ORS = "\n\n" }
>            { print $1, $2 }' BBS-list
-| aardvark;555-5553
-| 
-| alpo-net;555-3412
-| 
-| barfly;555-7685
...

ORSが改行を含んでいなければ、すべての出力は 陽に改行を出力しない限りは一行にまとまって出力されることになる。

Controlling Numeric Output with print

print 文を数値を出力するために使った場合、awkは内部で数値を (その数値を表す)文字列に変換し、その文字列を出力する。 awkはこの変 換動作のためにsprintf関数を使用する。(セクション Built-in Functions for String Manipulationを参照).現在のところ、sprintf 関数が数値(や文字列)をどのように書式化するかを記述されている format specificationを受諾し、数値の書式指定は違った方法が何種類もあるということ だけで十分である。書式の違いは セクション 書式制御文字を参照.で詳しく述べられている。

組込み変数のOFMTは、出力をおこなうときにprintsprintf を使って数値を文字列に変換するための書式のデフォルト設定を保持している。 OFMTのデフォルトの値は"%.6g"である。OFMTの値を違ったも のにすることによって、printが数値をどのように出力するかを変更するこ とができる。簡単な例を挙げよう。

$ awk 'BEGIN {
>   OFMT = "%.0f"  # 数値を整数として(丸めて)出力する
>   print 17.23 }'
-| 17

POSIX標準に従えば、OFMTに浮動小数点の変換指定ではない なにかをセットした場合のawkの動作は定義されてない(d.c.)。

Using printf Statements for Fancier Printing

あなたがprintで出力するには複雑な書式を使いたいのであれば、printf を使うと良い。 printfを使うことによってアイテムごとにその幅を指定し たり、数値を出力するのにそれをどのようなスタイルで出力するのかを指定するこ とができるようになる(使用する基数や、符号を出力するかどうか、小数点以下何 桁まで出力するか)。あなたは他の引数をどのように、どこに出力するかを制御する format stringと呼ばれる文字列によって、それを行なうことが可能である。

Introduction to the printf Statement

printf 文は次のような形式である。

printf format, item1, item2, ...

引数リスト全体をカッコで括ることもできる。このカッコはリストのいずれかの アイテムが関係演算子`>'を使った式であるときには必要となる。 カッコがないと、その文はリダイレクトと混同される可能性がある。 (セクション Redirecting Output of print and printfを参照).

printfprintの違いは引数formatにある。 これは文字列として扱われる式で、他の引数をそれぞれどのように 出力するかを指定する。これは書式文字列(format string)と 呼ばれる。

この書式文字列は ANSI Cライブラリのprintf関数のものと同じである。大 部分の書式は(書式文字列の)文字通りに出力されるテキストである。書式指定子 はアイテム一つ毎に一つの割りあいで、このテキスト中に置かれている。個々の書 式指定子は、次のアイテムをどのような書式で出力するかを指定している。

printf文は改行を自動的に付加することはせず、書式文字列で 指定されたものだけを出力する。 したがって、改行が必要ならば、書式文字列にそれを含めなければならない。 OFSORSといった変数にある出力セパレータは printfに対して何の影響も与えない。例えば、

BEGIN {
   ORS = "\nOUCH!\n"; OFS = "!"
   msg = "Don't Panic!"; printf "%s\n", msg
}

これは`Don't Panic!'というメッセージを出力する。

書式制御文字

書式指定子は`%' で始まり、(printf文でどのように出力するかを指定する) 書 式指定文字で終わる(`%'そのものを出力したい場合には `%%'と記述する)。 書式指定文字は値をどのように出力するかを指定する。書式指定子の残りは、どの位 のフィールド幅で出力するかというような事を指定する(省略可能な)修飾子である。

以下に書式指定文字の一覧を挙げる。

c
数値をASCIIキャラクタとみなして出力する。`printf "%c",65'`A'を 出力する。文字列を与えた場合は文字列の先頭にあるキャラクタを出力する。
d
i
どちらも同じで、十進整数を出力する。 `%i'はANSI Cとの互換性のための仕様である。
e
E
これは数値を科学(または指数)形式で出力する。 例えば、
printf "%4.3e\n", 1950
これは小数点以下を含めて全部で四つの数字からなる `1.950e+03'を出力する。 `4.3' は 修飾子(modifiers)であり、詳しくは後述する。 `%E'`e'の代わりに`E'を出力するものである。
f
浮動小数点形式で数値を出力する。例えば、
printf "%4.3f", 1950
これは小数点以下三桁を伴った四桁のsignificant figuresである `1950.000'を出力する。 `4.3' は 修飾子(modifiers)であり、詳しくは後述する。
g
G
科学表記か浮動小数点表記の、いずれか出力するキャラクタ数が少なくなる 方で出力する。結果が科学表記であったとき、 `%G'`E'`e'の代わりに使用する。
o
無符号の発進整数を出力する(八進数、もしくは八進表記は数字として`0' から `7'を使用する。十進数の8は八進数では`10'と表記される)
s
文字列を出力する
x
X
16進の符号なし整数を出力する(十六進もしくは十六進表記では、数字は`0' から`9'までと`a'から`f'である。十六進数字の`f'は十進 数の15を表わす)。`%X'`a'から`f'ではなく、`A' から `F'の文字を使用する。
%
これは本当は書式制御文字ではない、しかし`%'の後に続けて書かれた場合 には意味がある。`%%'と並べて書いたときには一文字の`%'を出力し、 引数を取らない。また、すべての修飾子を無視する。

整数指定の書式指定子を、C言語のlongで表わせる範囲外の 値に対して使ったとき、gawkは書式指定子を `%g'に切り替える。他のawk処理系では 不正な値を出力するか、完全に違うことをする。 (d.c.)

printfの書式の修飾子

書式指定には出力されるアイテムの値と、出力する大きさを制御するために 修飾子を含めることができる。修飾子は`%'と書式指定文字の間に置か れる。後で挙げる例では、出力中の空白を"*" というシンボルで表わし ている。以下は使用することのできる修飾子である。

-
マイナス記号は出力幅の修飾に使い、与えられた出力幅の中で左詰めを行うことを 指示する。通常は与えられた出力幅の中で右詰めで表示がなされる。 従って、次のような指定をすると、
printf "%-4s", "foo"
`foo*'が出力される。
space
数値の変換の際に、その値が正であればスペースを、負であればマイナス記号を 数値の前に置く。
+
プラス記号は幅指定の修飾子(後述する)の前で使用し、変換された数値が正の数 値であっても、その前に必ず符号をつけることを指示する。`+'はスペース 修飾子をオーバーライドする。
#
`%o'の前に置いた場合、数値の前にゼロを置く。 `%x'`%X'の前に置いた場合、出力する数値が0でなかったときに それに先行して`0x'`0X'を置く。 `%e', `%E', `%f' の場合、常に小数点をつけるようにする。 `%g', `%G'の場合、小数点以下の0も省略されないようにする。
0
%に続いた`0'はフラグとして動作し、出力のパディングを、スペースでは なく0で行うようにする。これは数値ではない出力書式のときも適用される(d. c.) このフラグはフィールド幅が実際に出力される値の幅よりも大きい場合にの み効果を持つ。
width
これはフィールドの幅を指定する数字である。 `%' と書式指定文字の間に置 かれ、この幅にフィールドを広げて出力を行うことを指定する。デフォルトではフィ ールドを埋めるためのスペースはフィールドの左から置かれる。 次のように指定した場合、
printf "%4s", "foo"
`*foo'を出力する。 width は(出力の)最小幅であって、最大幅ではない。アイテムの値が width よりも多くのキャラクタを必要としたならば、出力はその幅となる。 したがって、
printf "%4s", "foobar"
これは`foobar'を出力する。 マイナス記号を伴ったフィールド幅指定は、幅あわせのためのスペースを フィールドの左ではなく右に置く。
.prec
これは出力のときを精度を指定するのに使用する数字である。 書式指定が`e', `E', `f' の場合には、 この数字は小数点以下何桁まで出力したいかをしめす数字である。 書式指定が`g', `G' の場合、 有効数字の最大桁数を示す数字である。 `d', `o', `i', `u', `x', `X' といった書式指定の場合、出力する数値の最少桁数である。 文字列にたいしては、出力する文字列の最大文字数を指定する 数字となる。したがって、
printf "%.4s", "foobar"
この例の出力は `foob'となる。

Cライブラリのprintfは実行時にwidthprecを指定すること (例えば"%*.*s"のように)ができる。書式文字列中でwidthprecを記述する代わりに、引数リストでそれを渡す事ができる。例えば

w = 5
p = 3
s = "abcdefg"
printf "%*.*s\n", w, p, s

これは次の書き方と等しい。

s = "abcdefg"
printf "%5.3s\n", s

上のプログラムは両方とも`<**abc>'を出力する。

awk の初期のバージョンではこの機能がサポートされていなかった。次の様 に書式文字列を組み立てるのに文字列連接を使う事で、この機能をシミュレートす る事が可能である。

w = 5
p = 3
s = "abcdefg"
printf "%" w "." p "s\n", s

これは読み易いとは云えないが、きちんと働く。

Cプログラマはprintfの書式指定文字列中で`l'とsamp{h}というフ ラグを使っているかもしれない。これらはawkでは不正なフラグである。 大部分のawk処理系ではこれらを何の警告もなしに無視する。 `--lint'がコマンドラインで指定されている場合 (セクション コマンドラインオプションを参照)、gawkはこれらのフラグを 使用したときに警告を発する。同様に`--posix'が指定されている場合には 致命的エラーとなる。

printfを使った例

次の例は、printfを整列したテーブルの出力に どのように使用するかというものである。

awk '{ printf "%-10s %s\n", $1, $2 }' BBS-list

このプログラムは `BBS-list'というファイル中のBBSの名前($1) を10文字の文字列として、左寄せで出力する。同様に 電話番号($2)をそれに続いて出力する。 結果として、二つのカラムからなる、名前と電話番号の きちんと並んだテーブルが作成される。

$ awk '{ printf "%-10s %s\n", $1, $2 }' BBS-list
-| aardvark   555-5553
-| alpo-net   555-3412
-| barfly     555-7685
-| bites      555-1675
-| camelot    555-0542
-| core       555-2912
-| fooey      555-1234
-| foot       555-6699
-| macfoo     555-6480
-| sdace      555-3430
-| sabafoo    555-2127

なぜ電話番号を数値として出力するように指定していないのかわかるだろうか? ここ では数字がダッシュで区切られているので文字列として出力している。もし、これを 数値として出力しようとしたならば、そこで得られるものは最初の三つの数字 `555'である、これは混乱を招くだろう。

ここでは電話番号の出力時の幅を指定していない。それは 出力行の最後にあるものであり、その後ろにスペースを置く必要が ないからだ。

先頭のカラムにヘッダを付け加えることによってテーブルをより見やすいものに している。これを行う為に、BEGINパターン (セクション 特殊パターンBEGINENDを参照) を使ってヘッダをawkプログラムの始めで一度だけ出力している。

awk 'BEGIN { print "Name      Number"
             print "----      ------" }
     { printf "%-10s %s\n", $1, $2 }' BBS-list

この例ではprint文と printf文を混ぜて使っているのに 気がついただろうか?、同じ結果をprintf文だけを使って得る事ができる。

awk 'BEGIN { printf "%-10s %s\n", "Name", "Number"
             printf "%-10s %s\n", "----", "------" }
     { printf "%-10s %s\n", $1, $2 }' BBS-list

ヘッダと同じ書式指定を使って各カラムを出力しているので、ヘッダと 同じように桁揃えされる。

三回同じ書式を指定するのに、変数に書式を代入してその変数で指定する方法が ある。実例を挙げよう。

awk 'BEGIN { format = "%-10s %s\n"
             printf format, "Name", "Number"
             printf format, "----", "------" }
     { printf format, $1, $2 }' BBS-list

試しに以前に説明した (セクション The print Statementを参照). `inventory-shipped'の例の、表題と表のデータを printf文でそろえてみてほしい。

Redirecting Output of print and printf

これまでは出力は標準出力に対してのみ行われていた。 printprintfの両方とも別の場所に出力を送ることができる。 これはリダイレクトと呼ばれる。

リダイレクションはprint 文か printf文の後に書く事ができる。 awkにおけるリダイレクションはシェルコマンドのリダイレクションとよく似 ているが、awkではプログラムの中にリダイレクションの指示を書くという点 が違っている。

以下に、三種類の出力リダイレクションの例、 出力をファイルに送ったり、ファイルに追加したり、パイプを通して 他のコマンドに出力したりするものを挙げる。 これらの例ではprint文が使わ れているが、printf文を使っても同じように動作する。

print items > output-file
この書式のリダイレクションではアイテムの出力をoutput-fileという ファイルに対して行う。ファイル名output-fileは式であってもかまわない。 式を文字列に変換し、その後にファイル名として使用する (セクション を参照)。 この書式のリダイレクションは最初の出力を行う前に、output-file 、ファイ ルの削除を実行する。以後はoutput-file の削除はしないでファイルに追加す る形で出力を行う。もしoutput-file が存在しなければファイルが新たに作成 される。 たとえば、次に挙げるプログラムはBBSの名前のリストを`name-list'という名 前のファイルに、電話番号のリストを`phone-list'というファイルにそれぞれ 出力する。出力されたファイルの各行は、一つの名前あるいは番号で構成される。
$ awk '{ print $2 > "phone-list"
>        print $1 > "name-list" }' BBS-list
$ cat phone-list
-| 555-5553
-| 555-3412
...
$ cat name-list
-| aardvark
-| alpo-net
...
print items >> output-file
このリダイレクションは、出力をoutput-fileというファイルに対して行う。 先ほどの`>'での指定と違うのは、output-fileの削除が行われないとい うことである。出力はファイルに追加される形で行われる。 もしoutput-fileが存在していなければ、作成される。
print items | command
こうすることによって出力を、ファイルに対して行う代わりにpipeを通して渡 す事ができる。このやり方のリダイレクションは commandへのパイプをオープ ンし、そのパイプを通して、 commandを実行する為に作られたプロセスへ itemsの値を出力する。 リダイレクションの引数commandawkの式でも良い。 その式の値はコマンドを実行するための文字列に変換される。 次の例では二つのファイルが作られる。一つはソートされていないBBSの名前のリスト。 もう一つはアルファベットの降順にソートされたリストである。
awk '{ print $1 > "names.unsorted"
       command = "sort -r > names.sorted"
       print $1 | command }' BBS-list
この例のソートされていないリストは、ソート済みリストがパイプを通って sortユーティリティが出力する間に、通常のリダイレクトで書き込まれる。 次の例はリダイレクトを使って、メイリングリスト`bug-system'に従ってメイ ルを送るものである。これはトラブルにあったときに、システムメンテナンスの為に 定期的にawkスクリプトを実行するような場合に便利だろう。
report = "mail bug-system"
print "Awk script failed:", $0 | report
m = ("at record number " FNR " of " FILENAME)
print m | report
close(report)
メッセージは文字列連接と変数mに保持されている内容を 使って組み立てられている。作成されたメッセージはパイプラインを 通してmailプログラムに送られる。 ここでclose関数を呼んでいるのは、パイプを閉じてすぐに出力を送る ためである。 セクション Closing Input and Output Files and Pipesを参照, により詳しく記述されている。この例はファイル、コマンドを与えるのに変数を 使っている。つまり常に文字列定数を使う、というわけではないということで ある。 awk が毎回文字列値を要求するので、変数を使うというのは一 般にはいいアイデアである。

`>', `>>', `|' を使って出力をリダイレクトするときに、filecommandがそれまでにプログラム中で使っていなかったり出力する直前にク ローズを行っていたりすると、ファイルやパイプをオープンするためにシステムに問 い合わせを行う。

多くのawk処理系では、awkプログラムが オープンできるパイプラインの数はたった一つである! gawkではこのような制限はなく、使用しているオペレーティングシステム が許すだけパイプラインをオープンすることができる。

Special File Names in gawk

実行中のプログラムは、慣習的に三つの入出力ストリームを何もしなくても読み込み、 書き込みのために使えるようになっている。それらは標準入力, 標準出 力, 標準エラー出力として知られている。これらのストリームはデフォルト でターミナルの入出力に割り当てられている。しかし、しばしばシェルでのリダイレ クトによって(`<', `<<',`>', `>>', `>&' `|'と いったオペレータを使って)、変更される。標準エラー出力はエラーメッセージの出 力にだけ使われる。それは、標準出力、標準エラー出力の二つのストリームがあり、 別々にリダイレクトを行う事が可能であるからである。

他のawk処理系では、次のような方法でしか awkプログラ ムから標準エラー出力にエラーメッセージを出力する事ができない。

print "Serious error detected!" | "cat 1>&2"

これは標準エラー出力にアクセスするためにパイプを開いてawkプロセスの出 力を渡している。これはエレガントとは言い難いし、他のプロセスを必要とする非効 率的なやり方である。多くの人はこの点にあまり気を使っていないようなawk プログラムを書いている。こういったやり方に代えて、エラーメッセージを次のよう にしてターミナルに送る。

print "Serious error detected!" > "/dev/tty"

これは多くの場合同じ結果となるだろうが、常に、ではない。標準エラー出力は通常 ターミナルであるが、リダイレクトすることができ、その場合には出力はターミナル に対しては行われない。事実、awkをバックグラウンドジョブで実行すると、 そのプロセスはターミナルを持っておらず、`/dev/tty'のオープンは失敗する。

gawkは三つの標準ストリームにアクセスするために特殊なファイル名を持っ ている。gawkで入出力をリダイレクトするときにリダイレクト先のファイル 名が次の特殊な名前の中にあれば、gawkは直接(定義されている)ストリー ムを使用する。

`/dev/stdin'
The standard input (file descriptor 0). 標準入力(ファイルディスクリプタ0)。
`/dev/stdout'
標準出力(ファイルディスクリプタ1)。
`/dev/stderr'
標準エラー出力(ファイルディスクリプタ2)。
`/dev/fd/N'
ファイルディスクリプタnでアクセスされるファイル。このファイルはawk を実行しているプログラムによって(典型的なのはシェル)、オープンされていなけ ればならない。特別な操作をしない限り、ディスクリプタの0,1,2だけが使用可能で ある。

`/dev/stdin', `/dev/stdout', `/dev/stderr'等のファイル名は それぞれ`/dev/fd/0',
`/dev/fd/1', `/dev/fd/2'の 別名になっている。

gawkプログラムでエラーメッセージを出力する適当な手段は次の様に `/dev/stderr'を利用することである。

print "Serious error detected!" > "/dev/stderr"

gawkgawkが実行されているプロセスの情報にアクセスするために特 殊なファイル名を与えられている。これらの"ファイル"はそれぞれ、ひとつの情報 のレコードを表わしている。これらのファイルを二度以上読み込むためには、 最初にcloseをつかってクローズしなければならない。 (セクション Closing Input and Output Files and Pipesを参照). ファイルの名前は

`/dev/pid'
このファイルを読むと、カレントプロセスのプロセスIDが 十進数で、改行で終端されて返ってくる。
`/dev/ppid'
このファイルを読むと、カレントプロセスの親プロセスIDが 十進数で、改行で終端されて返ってくる。
`/dev/pgrpid'
このファイルを読むと、カレントプロセスのプロセスグループIDが 十進数で、改行で終端されて返ってくる。
`/dev/user'
このファイルを読むと、改行で終端されスペースで区切られたフィールドを持つ 一つのレコードが返ってくる。そのフィールドは以下のような情報を表している ものである。
$1
getuidシステムコールの返す値(実ユーザーID番号)。
$2
geteuidシステムコールの返す値(実効ユーザーID番号)。
$3
getgidシステムコールの返す値(実グループID番号)。
$4
getgidシステムコールの返す値(実効グループID番号)。
さらに追加のフィールドがあるなら、getgroupsシステムコールが返した グループIDである(Multiple グループはすべてのシステムでサポートされている わけではない)。

これらの特殊ファイルはコマンドライン上でデータファイルのように使ってもよ いし、awkプログラムの中で入出力のリダイレクトで使ってもよい。ただ し、`-f'オプションを伴ったソースファイルとしては使うことはできない。

gawKが互換モード(セクション コマンドラインオプションを参照) で動作しているときには、これらの特殊ファイルの認識は禁止される。

警告: あなたの使うシステムが`/dev/fd'というディレクトリ (あるいは先に述べたような特殊ファイル)を持っていないのであれば、これらのファ イル名をgawkそれ自身が解釈する。例えば、 `/dev/fd/4'を使ってファ イルディスクリプタの4 番に出力しようとすると、ファイルディスクリプタの4番が dupされ、その結果の新しいファイルディスクリプタに出力が行なわれる。こ のことはほとんどの場合重要なことではないが、重要なのはファイルディスクリプタ の0、1、2番に関係するファイルをクローズしないということである。もし、これら のうちどれかをクローズしてしまったならば、その結果は予測できないものとなる。

プロセスに関連した情報を提供する特殊ファイルは、将来のバージョンのgawk ではなくなる可能性がある。 セクション 将来予定されている拡張を参照.

Closing Input and Output Files and Pipes

もし同じファイル名や同じシェルコマンドが、awkプログラムの実行中に二度 以上getline (セクション getlineを使った入力を参照) と一緒に使われた場合、ファイルのオープンやコマンドの実行は 最初の一回だけ行われる。つまり最初にファイルやコマンドからレコードを読み込む ときである。次にgetlineを使って読むときは同一のファイル、コマンドから 別のレコードを読み込む。

同様にファイルやパイプが出力のためにオープンされたとき、 awkは(オープンした情報を)そのファイル名やコマンド名と結び付け、 後になって出力したときにその出力をそれまでのものに追加する形で行う。 ファイルやパイプはawkが終了するまでオープンされている。

このことによって、同じファイルを再び最初から読み始めたいときや、シェルコマン ドを再実行(コマンドの出力からもっと読みだしたいとき)したいようなときには特 別な手順を踏まねばならない。つまり、次の例のようにclose関数を使わなけ ればならない。

close(filename)

or

close(command)

引数filenamecommandは任意の式であってよい。その値は、ファ イルをオープンしたりコマンドを起動した文字列と(スペースや他の"irrelevant" (無関係)なキャラクタも含めて) 正確にマッチしなければならない。例え ば、次のようにパイプをオープンしたら、

"sort -r names" | getline foo

次のようにクローズしなければならない。

close("sort -r names")

一度この関数呼びだしが実行されると、次のファイルやコマンドからの@code {getline}や、ファイルやコマンドに対するprintprintfは、フ ァイルの再オープンやコマンドの再実行を行う。

ファイルやパイプをクローズするときの式は、それらをオープンしたり、コマ ンドを起動したときの文字列とまったく同じものでなければならない。これファ イル名やコマンドを格納するために変数を使ってみるのにいい題材である。例え ば、パイプを次のようにしてオープンしたならば、

先程の例はこのように書くことができる。

sortcom = "sort -r names"
sortcom | getline foo
...
close(sortcom)

これは、awkプログラムに見つけづらい打ち間違いのエラー (typographical errors)が入り込むのを防ぐのに役立つ。

以下に出力ファイルをクローズする必要があるかもしれない理由を幾つか挙げる。

closeはクローズに成功した時0を返し、失敗したときに0以外を返す。 失敗した場合には変数ERRNOにエラーの発生を示す文字列がセットされる。

システムがオープンすることを許している以上の数のファイルを使おうした場合、 gawkは使っているデータファイルの中で多重オープンを 試みる。 gawkのこれをおこなう能力はあなたが使っているオペレーティングシステ ムの能力に依存する。したがって、ファイルを使いおわったら常にclose するということがよいやり方であるし、移植性のためによいのである。


移動先 先頭, , , 末尾 セクション, 目次.