組み込み関数とはawk
プログラムで常に呼び出す事のできる関数である。
この章ではawk
の全ての組み込み関数を定義する。一部のものは別のセクショ
ンで説明がされているが、便宜のためここでも簡単にまとめてある
(ユーザーは自分で新たに関数を定義する事もできる
セクション ユーザー定義関数を参照.)。
組み込み関数を呼び出すには、関数の名前に続けて括弧で囲まれた引数を書けばよい。
例えばatan2(y + z, 1)
は関数atan2
を二つの引数で呼び出す。
組み込み関数の名前と、開き括弧の間にある空白は無視される。しかし、そういった 空白は使わないようにすることを勧めたい。ユーザー定義の関数ではこのような空白 を許されておらず、関数名の直後に空白をおかないという単純なやり方でそのような 間違いを簡単に見つけ出せる。
組み込み関数はそれぞれ、特定の数の引数を受け取る。多くの場合、組み込み関
数に対して余計に多く渡された引数は無視される。引数が省略されたときのデフ
ォルトの扱いは個々の関数毎に決められている。一部のawk
処理系では、
組込み変数に余計な引数を渡した場合はそういった引数は無視されていた。しか
しawk
では、それは致命的なエラーとなる。
関数が呼び出されるとき、関数の実引数は実際に関数が呼び出される前に完全に評価 され、式が作り出される。例えば次のようなコードでは
i = 4 j = sqrt(i++)
変数i
は、sqrt
に対する実引数の値として4がセットされて関数が呼ば
れる前に 5がセットされる。
関数に対する実引数を評価する順番は定義されていない。そのため、 実引数が左から右へ順番に評価されるということを仮定したプログラムを 書くべきではない。例えば、
i = 5 j = atan2(i++, i *= 2)
上記のようなプログラム片があったとして、評価の順番が左から右であったとす
ると、i
は最初に6になり、ついで12となり、それからatan2
が実
引数6と12で呼び出されるしかし、評価が右から左へ行われたとすると、@code
{i}は最初に10となり、ついで11になる。その後atan2
の呼び出しが実引
数11と10で行われる。
以下のリストは、数値を扱うすべての組込み関数である。 省略可能な引数はブラケット("[" と "]")で囲まれている。
int(x)
int(3)
は 3、 int(3.9)
は 3、 int(-3.9)
は
-3、そして int(-3)
は -3 となる。
sqrt(x)
sqrt(4)
は2である。
exp(x)
log(x)
sin(x)
cos(x)
atan2(y, x)
y / x
のアークタンジェントを返す(単位はラジアン)。
rand()
rand
の返す値は0から1の範囲の数であり、0と1は含まれない。
しばしば整数の乱数を必要とするだろうが、次に n未満の非負の整数の乱数を
返すユーザー定義関数を挙げる。
function randint(n) { return int(n * rand()) }この例での掛け算は0より大きく、n未満の実数を作り出す。それを(
int
を使って)0からn - 1
の間の整数にする。
次の例は先ほどのものと同じ様な、1からnの間の整数を返す関数を使っている。
このプログラムはレコード入力の度に新しい乱数を出力する。
awk ' # サイコロをシミュレートする関数 function roll(n) { return 1 + int(rand() * n) } # 三つの六面体サイコロを振り、 # その合計を出力する。 { printf("%d points\n", roll(6)+roll(6)+roll(6)) }'注意:
gawk
も含めて、大部分のawk
処理系では実行の度
にrand
は、同じ数値、もしくは種から数値を作り出しはじめる。
このことはプログラムを実行する度に同じ結果が生成されるということである。
その数値はひとつのawk
プログラムの中ではランダムであるけれども走ら
せるごとに予想できるものである。これはデバッグには便利であるけれども、使
う度毎に違う結果を必要とするような場合には実行する毎に乱数の種を違ったも
のにしなければならない。それを行うにはsrand
を使用する。
srand([x])
srand
は乱数を生成するための出発点、もしくは種の値として
xをセットする。
それぞれの種は各々特定の"乱数列"
(11)
を導き出す。従って、乱数の種として同じ値を
二度目にセットしたとすると、同じ"乱数列"を得ることになる。
srand()
の引数xを省略した場合、乱数の種としてその時点の日時が使
用される。この方法は予測できないような乱数列を得られる。
srand
の返す値は以前使われていた乱数の種である。これによって以前の乱数
系列をもう一度作り出すことが簡単になる。
このセクションにある関数は一つ以上の文字列を検索したり変更したりするものである。 省略可能な引数はブラケット("[" と "]")で囲まれている。
index(in, find)
$ awk 'BEGIN { print index("peanut", "an") }' -| 3もしfindが見つからなかったなら、
index
は0を返す
(awk
での文字列の添字は1から始まると言うことを思い出して欲しい)。
length([string])
length("abcde")
は5であるが、length(15 * 35)
の結果は 3である。
それは15 × 35 = 525で、この525は三つのキャラクタからなる `"525"'という
文字列に変換されるからである。
引数が省略された場合、length
は$0
の長さを返す。
古いバージョンのawk
では、length
関数を括弧なしで呼ぶことができ
る。それは POSIX の標準では"deprecated"とされる。このことは、プログラム中
でこういった書き方が将来のバージョンでは使えなくなるかも知れないということで
ある。従って、awk
プログラムの移植性を最大にするために括弧を常に書くべ
きである。
match(string, regexp)
match
関数はstringから、正規表現regexpにマッチする部分文字
列の中で、最も左にあり、もっとも長い部分文字列を検索し、部分文字列が始まる場
所を返す(stringの最初から始まっていれば1)。マッチするものが見つから
なかった場合、0を返す。
match
関数は組み込み変数のRSTART
にインデックスをセットし、同様
に組み込み変数RLENGTH
にマッチした部分文字列の長さをセットする。マッチ
しなかった場合には、RSTART
には0が、RLENGTH
には -1がセッ
トされる。
例えば、
awk '{ if ($1 == "FIND") regex = $2 else { where = match($0, regex) if (where != 0) print "Match of", regex, "found at", \ where, "in", $0 } }'このプログラムは変数
regex
に格納されている正規表現にマッチする行を探す。
この正規表現は変更することができる。ある行の最初の単語が`FIND'であった
場合、 regex
はその行の二番目の単語に変更される。従って、次のようなデー
タを与えると
FIND ru+n My program runs but not very quickly FIND Melvin JF+KM This line is property of Reality Engineering Co. Melvin was here.
awk
の出力は次のようになる。
Match of ru+n found at 12 in My program runs Match of Melvin found at 1 in Melvin was here.
split(string, array [, fieldsep])
array[1]
に、二番目
の要素は array[2]
に格納され、以下の要素も同様である。三番目の引
数fieldsepの文字列値は、 stringを分割する場所を指定する
(FS
が入力レコードを分割する場所にマッチする正規表現であるように)正
規表現である。 fieldsepが省略されると、FS
の値が使われる。
split
は作り出された要素の数を返す。
split
関数はまた、入力行をフィールドに分割するとの同じ様なやり方で文字
列を分割する。例えば、
split("cul-de-sac", a, "-")これは`-'をセパレータとして、`auto-da-fe'という文字列を三つのフィ ールドに分割し、配列
a
の要素を以下のようにセットする。
a[1] = "cul" a[2] = "de" a[3] = "sac"
split
を呼び出して返ってくる値は3である。
入力フィールドを分割するときと同じ様に、fieldsepの値が" "
であ
る場合には先頭や末尾にある空白は無視され、要素は空白で区切られる。
また同様に、fieldsepが空文字列であれば、個々のキャラクタが配列の要
素となるように分割がおこなわれる(これはgawk
特有の拡張である)。
最近のgawk
処理系では、gawk
も含めて、この関数の第三引数に文
字列だけでなく(/abc/
)のような正規表現定数を許している。(d.c.)
POSIXの標準も同様である。
文字列の分割に先立って、split
は配列arrayの
要素をすべて削除する(d.c.)
stringのどこにもfieldsepにマッチするものがない場合、
arrayは一つの要素を持つようになる。その要素の値は、
元々のstringと同じである。
sprintf(format, expression1,...)
printf
がその引数を渡されたときに出力するであろう文字列を
(出力はせずに)返す。
(セクション Using printf
Statements for Fancier Printingを参照).
例えば、
sprintf("pi = %.2f (approx.)", 22/7)returns the string
"pi = 3.14 (approx.)"
.
これは"pi = 3.14 (approx.)"
という文字列を返す。
sub(regexp, replacement [, target])
sub
関数はtargetの値を変更する。検索する値は文字列でなければなら
ず、そしてそれは regexpで与えられる正規表現にマッチする部分文字列の中
で一番左にあり、長さが一番長いものである文字列全体の内マッチしたテキストは
replacementで置き換えられる。
置き換えられた文字列はtargetの新しい値となる。
この関数は独特である。それは、targetが単に値を計算するのに使われるので
はなく、式ではないということからくる。 targetは変数、フィールド、配列
の参照のように変更された値を格納できるものでなければならない。この引数が省略
された場合にはデフォルトとして$0
が使用される。
例を挙げよう。
str = "water, water, everywhere" sub(/at/, "ith", str)この例では
str
に"wither, water, everywhere"
をセットし、その
中で最も左にあり、もっとも長い`at'を`ith'に置き換える。
sub
関数は置き換えを行った数(つまり1か0のいずれか)を返す。
replacement中にスペシャルキャラクタ`&'があると、それはregexp
にマッチした部分文字列を表す。 (もしこの正規表現が二つ以上の文字列にマッチす
るのならば、 `&'が表す部分文字列が変化するだろう) 例えば、
awk '{ sub(/candidate/, "& and his wife"); print }'これは各入力行で最初に現れる`candidate'を`candidate and his wife'に 変更する。 別の例を挙げよう。
awk 'BEGIN { str = "daabaaa" sub(/a*/, "c&c", str) print str }' -| dcaacbaaaこの例では`dcaacbaaa'が出力される。これは`&'は非文字定数として扱わ れ、"最左最長"の規則に従っている為である。 (セクション How Much Text Matches?を参照)。 スペシャルキャラクタ(`&')の効果はその前にバックスラッシュを付けることに よって抑制することができる。例によって、文字列中に一つのバックスラッシュを入 れるためにはバックスラッシュを二つ続けて書かなければならない。従って、置換文 字列中に`&'という文字を含ませるには`\\&'と記述する。次に挙げる例は 各行で最初に現れる`|'を`&'で置き換える。
awk '{ sub(/\|/, "\\&"); print }'ノート:上述のように、
sub
の三番目の引数は左辺値でなければならな
い。一部のawk
処理系には三番目の引数として左辺値でない式を許すものもある。
そういった場合、sub
はパターンを検索し、0か1を返すけれども、置き換え(起
こったとして)の結果は、それを格納する場所がないので失われる。そのような
awk
は次のような式を受け付ける。
sub(/USA/, "United States", "the USA and Canada")過去のものに対する互換性のために、
gawk
はこのような間違ったコード
を受容する。しかしながら、第三引数として別の変更不能なオブジェクトを
使った場合には致命的エラーを引き起こす結果となり、プログラムを実行する
ことができないだろう。
結局のところ、regexpは正規表現定数ではなく、文字列へと変換され
その文字列値がマッチすべき正規表現として取り扱われるものである。
gsub(regexp, replacement [, target])
sub
と似ているが、gsub
はもっとも長く、最も左にあり、
それぞれが重ならないようなマッチした部分文字列をすべて置換する。
gsub
の`g'は全ての場所で置換を行う"global"を意味する。次の例で
は、
awk '{ gsub(/Britain/, "United Kingdom"); print }'全ての入力レコードで、`Britain'という文字列を全て `United Kingdom' に置き換える。
gsub
関数は置き換えが起こった回数を返す。検索と置換の対象となる変数
targetが省略された場合、入力レコード全体、つまり$0
が使用される。
sub
と同じ様に、`&' と `\'の二つのキャラクタは特殊な意味があ
り、また三番目の引数は左辺値でなければならない。
gensub(regexp, replacement, how [, target])
gensub
は汎用的な置換関数である。sub
やgsub
のように
対象文字列targetから正規表現regexpに
マッチする部分を検索する。sub
やgsub
と違うのは、
関数の戻り値として置換が行われた文字列を返し、
元の文字列を変更しないという点である。
もしhowが`g'か`G'で始まる文字列であれば、
regexpにマッチする全てのものをreplacementに置き換え、
そうでない場合には
howは何番目にマッチしたものを
regexpで置き換える
かを指示する。
targetが渡されなかった場合、$0
が代わりに
使われる。
gensub
には、
置換テキストの中で正規表現の構成要素を指定する
というsub
やgsub
にはない機能
が追加されている。
これはマークする正規表現を括弧で囲み、置換テキスト
の中で`\n'を使って指定する。
nは1から9までの数字である。
例えば、
$ gawk ' > BEGIN { > a = "abc def" > b = gensub(/(.+) (.+)/, "\\2 \\1", "g", a) > print b > }' -| def abc
sub
で説明したように、文字列中でバックスラッシュを一つ
置くためには、二つタイプしなければならない。
置換テキスト中では、`\0'は`&'と同じように
マッチしたテキスト全体を表わす。
次の例は、三番目の引数を置き換えの対象となる
(正規表現にマッチした)テキストを指定するために
どのように使うかを表わしている。
$ echo a b c a b c | > gawk '{ print gensub(/a/, "AA", 2) }' -| a b c AA b cこの場合、
$0
がデフォルトの(置き換えの)対象文字列として
使用される。gensub
は置き換えを行った結果の新しい
文字列を戻り値として返し、それは直接print
で出力する
ものとして(print
に)渡される。
もし引数howが`g'でも`G'でも始まっていない
文字列や、0よりも小さい数値であったとすると、
一度だけ置換が行われる。
regexpがtargetにマッチしなかった場合、gensub
の
戻り値は元の値であり、targetを変更することはない。
gensub
はgawk
の拡張であり、
互換モード(セクション コマンドラインオプションを参照)では
使用できない。
substr(string, start [, length])
substr("washington", 5, 3)
は"ing"
を返す。
lengthが与えられない場合、この関数はstringで start番目から
始まる残りの部分全てを返す。例えば、substr("washington", 5)
は
"ington"
を返す。 lengthがstart番目から文字列の終端までの
長さよりも長い場合も同様である。
注意:substr
が返す文字列に代入することはできない。
したがって、以下に示す例のようにして文字列の一部を変更しようとすることは
間違いである。
string = "abcdef" # "abCDEf"を得ようとしているが、うまく行かない substr(string, 3, 3) = "CDE"また、
sub
やgsub
の第三引数としてsubstr
を使うのも
間違いである。
gsub(/xyz/, "pdq", substr($0, 5, 20)) # 間違い
tolower(string)
tolower("MiXeD cAsE 123")
は "mixed case 123"
を返す。
toupper(string)
toupper("MiXeD cAsE 123")
は "MIXED CASE 123"
を返す。
sub
, gsub
and gensub
sub
, gsub
, gensub
を使っているときに
バックスラッシュやアンパサンド(&
)を使おうとするときは、
これらの文字が幾つかの段階で
エスケープ処理(escape processing)される
ことに注意する必要がある。
第一に、awk
がプログラムを読み込んで
内部にプログラム実行のためのコピーを作るときに
単語レベル(lexical level)で。
さらに、awk
が生成する置換文字列を実際にスキャンするときに
実行時レベル(run-time level)で。
これらの両方のレベルで、awk
はバックスラッシュの後に来ることのでき
るキャラクタの集合を検索する。レキシカルレベルでは、セクション エスケープシーケンスを参照.
に挙げられているようなエスケープシーケンスの検索をする。した
がって、awk
が実行時レベルで`\'を処理するには、レキシカルレベ
ルで二つの`\'をタイプする。エスケープシーケンスとして正しくないキャ
ラクタが`\'の後に来たときは、UNIXのawk
やgawk
の両方と
も単純に`\'を取り去って、その後のキャラクタを文字列に送る。
だから、"a\qb"
は"aqb"
のように扱われる。
実行時レベルでは、幾つかの関数が`\'と`&'のシーケンスを違ったや り方で扱う。この状況は(残念だが)ちょっとばかり複雑である。
伝統的にsub
と gsub
という関数は、`\&'というキャラクタ
二つの並びを特別に扱っていて、このシーケンスは一つの`&'の置き換えら
れたが、文字列replacement中にある、`&'の前にない`\'は変更
されずにそのままにされた。これを表にすると以下のようになる。
この表はレキシカルレベルの処理で奇数個のバックスラッシュが実行時レベルで
は偶数個になったものと、実行時にsub
が処理した結果の両方がある(単
純のため、この後の表ではレキシカルレベルで偶数個の`\'がある場合だけ
を例示する)。
伝統的アプローチに関する問題は、 `\'というリテラルにマッチしたテキストが続くというものを取得する 手段がない、ということである。
1992年のPOSIX標準はこの問題を解決した。この標準では、sub
と
gsub
は`\'の後の`\' にも `&'にも注目するということ
を述べている。もし、`\'に続いて何かあれば、そのキャラクタはそのキ
ャラクタそのものとして出力される。`\'と`&'の解釈は以下のように
なった。
これは問題を解決したかのように見える。しかし残念ながら、標準で述べている ことは一般的ではない。標準では、`\'はその直後にある`\'と`&' 以外のすべてのキャラクタの特殊な意味を打ち消すと主張しているが、 その特殊な意味は定義されていない。これは二つの問題に繋がる。
awk
プログラムを破壊する。
awk
プログラムを確実に可搬性のあるものにするには、
文字列replacementにあるすべてのキャラクタ
の前にバックスラッシュを置かなければならない。(12)
POSIXの標準は改定中である。(13) 上で述べた理由によって、よりオリジナルの結果に一致させるために標準の 改定が提案された。提案されたルールは`\'をマッチしたテキストの前 に置くのを可能にするために、特別なケースを持つ。
実行時レベルでは、現在三つの特殊なキャラクタ並び、`\\\&', `\\&', `\&'があるが、伝統的には一つしかない。しかし、伝統的なケースの ように、これら三つのシーケンスの一部ではない`\'は、そのまま出力に現 れる。
gawk
3.0 follows these proposed POSIX rules for sub
and
gsub
.
これら提案された規則が実際に標準に取り入れられるかどうかは現時点
ではわからない。これからのリリースのgawk
では、標準(それが
最終的な仕様であるかどうかに関らず)への追随をするだろう。この
マニュアル も同様に更新されるだろう。
gensub
のルールはかなり単純である。実行時レベルでは、gawk
は
`\'を見つけると、その後ろに数字が続いている場合には、(その数字に対
応する)以前に現れているカッコで括られた部分正規表現にマッチしたテキスト
が出力テキストに現れる。それ以外の場合、`\'の後ろのキャラクタはなん
の意味もなく、そのキャラクタがそのまま出力テキストに現れるが、`\'は
出力されない。
レキシカルレベルの処理や実行時レベルの処理は複雑なので、sub
や
gsub
には特殊ケースがある。あなたが置換を実行するときには、
gawk
と、gensub
の使用を勧める。
以下に挙げる関数は入出力(I/O)に関係するものである。 省略可能な引数はブラケット("[" と "]")で囲まれている。
close(filename)
fflush([filename])
fflush
の目的である。
gawk
もまたその出力をバッファリングしており、fflush
関数は
gawk
のバッファを強制的にフラッシュさせるために使うことができる。
fflush
は最近(1994年)にベル研究所で開発されたawk
で
追加された。これはPOSIXの標準ではなく、`--posix'がコマンドラインで
指定された場合(セクション コマンドラインオプションを参照)は
使用できない。
gawk
はfflush
関数を二つの方法で拡張した。一つは、引数なしの
場合を認めたというものであり、この場合は標準出力のバッファがフラッシュさ
れる。もう一つは、引数として空文字列(""
) を認めたというもので
あり、これはすべてのオープンされているファイル、パイプをフラッシ
ュする。
fflush
はバッファのフラッシュに成功した場合は0を返し、
それ以外では非0を返す。
system(command)
awk
プログラムに戻るということをできるようにする。
関数system
はcommandで渡された文字列をコマンドとして
実行する。コマンドから戻ってきたとき、
実行したコマンドの終了ステータスを関数の値として返す。
例えば次のコード片をawk
プログラムに埋めこむと、
END { system("date | mail -s 'awk run done' root") }システム管理者はこの
awk
プログラムが
入力を処理し終わって入力終了処理が始まったときに
メイルを受け取ることになる。
パイプに対してprint
やprintf
をリダイレクト
することはほとんどの場合仕事を達成するのに十分である。
多くのコマンドを実行する必要があるのなら、シェルに対する
パイプに対して単純に出力してやることで効率良く行うことが
できるだろう:
while (more stuff to do) print command | "/bin/sh" close("/bin/sh")しかしながら、
awk
プログラムが対話的なものであったときには、
system
はシェルやエディタのような
大きなself-containedプログラムを用意するのに便利である。
一部のオペレーティングシステムではsystem
関数を
実装することができない。サポートされていない場合にはsystem
は
致命的エラーを引き起こす。
バッファリングというものは、あなたのプログラムが対話的(interactive) であろうがなかろうが、根の深い混乱を招く可能性がある。たとえば、 キーボードの前に坐っているユーザーとのやり取りを考えてみよう(14)
対話的なプログラムは一般的にはその出力は行バッファ、つまり 各行毎に出力を行うものとなっている。対話的でないプログラムは バッファがいっぱいになるまで実際に出力するのを待ち、複数行が バッファに溜まっているということもある。
以下に挙げるのはその違いを示す例である。
$ awk '{ print $1 + $2 }' 1 1 -| 2 2 3 -| 5 Control-d
各行は即座に出力されている。これを以下の例と比較してみよう。
$ awk '{ print $1 + $2 }' | cat 1 1 2 3 Control-d -| 2 -| 5
ここでは、Control-dがタイプされるまで、何も出力されていない。
これはバッファリングされているためであり、それがcat
に対する
パイプへ(一度に)送られているからである。
system
関数fflush
はファイルやパイプに対する出力のバッファリングを
陽に制御する機能を提供する。しかしこれは、他のawk
処理系では
使えないのでこれを使うと可搬性(portability)に欠けることになる。
出力バッファをフラッシュするための手段として、system
関数を
空文字列を引数にして呼び出すというものがある。
system("") # 出力をフラッシュする
gawk
はこのようなsystem
関数の使い方を特殊なものとして
みなし、シェル(あるいは他のコマンドインタープリター)を何のコマンドも
なしに起動するようなことはしない。このため、gawk
では
この使い方は便利であるばかりでなく、効率も良い。
このやり方は他のawk
処理系でも使えることが多いので、
必要ないシェルを起動してしまうことを避ける必要もない
(他の処理系では、標準出力のバッファだけがフラッシュされ、その他の
出力バッファはフラッシュされないかもしれない)。
もし、プログラマーが期待することを考えているのなら、system
が
すべてのペンディングされている出力をフラッシュするだろうことが
役に立つだろう。
BEGIN { print "first print" system("echo system echo") print "second print" }
このプログラムは
first print system echo second print
上記のような出力をするはずで、下に示すようなものではない。
system echo first print second print
もしawk
がsystem
を実行する前にバッファをフラッシュしなければ、
後者のような(期待しない)出力がでてくることになる。
awk
プログラムの common useは、特定のレコードが記録された
時刻を示すタイムスタンプ情報からなるログファイルに対する処理である。
多くのプログラムは、タイムスタンプをtime
というシステムコール
が返すある特定の時点からの経過秒数の形で記録する。
POSIX システム上では、これは UTCの1970年1月1日の午前零時からの
経過秒数である。
このようなログファイルの処理をより簡単にして便利なレポートを
生成するために、gawk
にはタイムスタンプに関連する働きをする
二つの関数がある。これらの関数は両方ともgawk
での拡張であり、
POSIXの標準にもgawk
以外のawk
処理系にもない。
省略可能なパラメーターは、角カッコ("[" と "]")で囲まれている。
systime()
strftime([format [, timestamp]])
systime
が返した値と同じ書式である。
引数timestampが省略された場合、gawk
は
タイムスタンプとして現在時刻を使用する。
引数formatが省略された場合、
code{strftime}は"%a %b %d %H:%M:%S %Z %Y"
を
使用する。この書式文字列は
date
ユーティリティの出力と(ほぼ)同じ出力を生成する
(3.0以前のバージョンのgawk
は引数formatを省略することは
できなかった)。
systime
関数はログファイルの日付、時間と、プログラムを実行している時点
の日付、時間とを比較することを可能にする。特に、ある特定のレコードが記録され
てからどれくらいたったのかを求めることが簡単になる。それはまた、"seconds
since the epoch"フォーマットを使ってログのレコードを作成することを可能にす
る。
strftime
関数はタイムスタンプを、人間が読み易い情報に変換するのを簡単
にさせる。この関数はsprintf
関数
(セクション Built-in Functions for String Manipulationを参照)
に似ていて、書式指定でないキャラクタはその
まま文字列として返され、書式指定文字列中で日付や時刻を特定するものがあるとそ
れを置き換える。もし、timestampが省略されると gawk
は代わりに実
行時の時間を使う。
strftime
は、ANSI の標準Cがサポートする以下の書式指定を使用できる。
%a
%A
%b
%B
%c
%d
%H
%I
%j
%m
%M
%p
%S
%U
%w
%W
%x
%X
%y
%Y
%Z
%%
変換指定文字が上に挙げたものに含まれていない場合には、その結果は未定義で ある。(16)
非公式に、 localeはプログラムを実行する地理的な場所である。例えば、ア
メリカ合衆国では1991年9月4日を略して書き表わす普通のやり方は "9/4/91"であ
る。ヨーロッパの多くの国ではそれを"4.9.91"のように記述する。したがって、ア
メリカにおいては`%x'という指定は `9/4/91'という結果となり、ヨーロッ
パでは`4.9.91'という結果となる。 ANSI 標準Cでは大部分のCプログラマーが
使うであろう環境でのデフォルトのC
ロカール(locale)を定義している。
gawk
のための
パブリックドメインバージョンのstrftime
は ANSIに完全にしたがった形では
書かれていない。そういったものをgawk
のコンパイルのときに使用すれば
(セクション gawk
をインストールするを参照.)、次に挙げるような書式指定も
行なうことが可能である。
%D
%e
%h
%n
%r
%R
%T
%t
%k
%l
%C
%u
%V
%G
%g
%Ec %EC %Ex %Ey %EY %Od %Oe %OH %OI
%Om %OM %OS %Ou %OU %OV %Ow %OW %Oy
date
ユーティリティに従うことを容易にする。)
%v
%z
次に挙げるサンプルは、awk
によるPOSIXのdate
ユーティリティの
実現である。通常は、date
ユーティリティは、現在の日付と時刻をよく
知られた書式で出力する。しかし、`+'で始まる引数を与えた場合、
date
はその引数の非書式指定部分はそのまま標準出力にコピーし、現在
時刻にしたがって、文字列中の書式指定子を解釈する。例を挙げよう。
$ date '+Today is %A, %B %d, %Y.' -| Today is Thursday, July 11, 1991.
以下のプログラムはgawk
バージョンのdate
ユーティリティである。
タイムゾーンがUTCにセットされたかのようにdate
を実行させる
`-u'オプションを取り扱うために、
シェルラッパー(shell wrapper)がある。
#! /bin/sh # # date -- approximate the P1003.2 'date' command case $1 in -u) TZ=GMT0 # UTCを使う export TZ shift ;; esac gawk 'BEGIN { format = "%a %b %d %H:%M:%S %Z %Y" exitval = 0 if (ARGC > 2) exitval = 1 else if (ARGC == 2) { format = ARGV[1] if (format ~ /^\+/) format = substr(format, 2) # 先頭の +を取り除く } print strftime(format) exit exitval }' "$@"