awk コマンド

目的

ファイルでパターンに一致する行を検出し、検出された行に対して指定されたアクションを 実行します。

構文

awk [ -u ] [ -F Ere ] [ -v Assignment ] ... { -f ProgramFile | 'Program' } [ [ File ... | Assignment ... ] ] ...

説明

awk コマンドは、ユーザー指定の一連の命令を使用し、ユーザー指定の拡張正規表現に照らして、一度に 1 行ずつ一組のファイルを比較します。 次に、この拡張正規表現と一致する行に対してアクションが実行されます。

awk コマンドによるパターン検索は、grep コマンドの場合より汎用性があり、ユーザーは入力テキスト行に対して複数のアクションを実行できます。 awk コマンド・プログラミング言語はコンパイルの必要がないので、変数、数字関数、文字列関数、および論理演算子を使用できます。

awk コマンドは、LANGLC_ALLLC_COLLATELC_CTYPELC_MESSAGESLC_NUMERICNLSPATH、および PATH 環境変数から影響を受けます。

この項目では、次のトピックについて説明します。

awk コマンドの入力

awk コマンドは、入力テキスト・ファイルとプログラム命令の 2 種類の入力を受け入れます。

入力テキスト・ファイル

検索とアクションは入力テキスト・ファイルに対して実行されます。 ファイルは次のようにして指定されます。

  • コマンド・ラインで File 変数を指定する。
  • 特殊変数 ARGVARGC を変更する。
  • File 変数がない場合には標準入力を与える。

File 変数に複数のファイルが指定されている場合は、指定されている順にそれらのファイルが処理されます。

プログラム命令

ユーザーが指定した命令は、awk コマンドのアクションを制御します。 命令は、コマンド・ラインの `Program' 変数、または -f フラグと ProgramFile 変数で指定されたファイルの、どちらかから取り出されます。 複数のプログラム・ファイルが指定された場合には、指定された順にファイルが連結され、その結果としての命令の順番が使用されます。

awk コマンドの出力

awk コマンドは、入力テキスト・ファイル内のデータから、次の 3 種類の出力を作成します。

  • 入力ファイルに変更を加えないで、選択したデータを標準出力に出力できます。
  • 入力ファイルの一部を選択して変更できます。
  • 入力ファイルの内容に変更を加えるかまたは変更を加えないで、選択したデータを変更して標準出力に出力できます。

これらの 3 種類の出力のすべてを、同一のファイルに対して実行できます。 awk コマンドが認識するプログラミング言語を使用して、ユーザーは出力をリダイレクトすることができます。

レコードとフィールドによるファイル処理

ファイルは次の方法で処理されます。

  1. awk は、指定された命令をスキャンし、入力ファイルを読み取る前に実行するように指定されたすべてのアクションを実行します。

    awk プログラミング言語の BEGIN ステートメントで、最初のレコードの読み取り前に実行する一連の命令を指定できます。 これは、特殊変数を初期化するときに特に役立ちます。

  2. 1 つのレコードが入力ファイルから読み取られます。

    レコードは、レコード分離文字で区切られたデータの集合です。 レコード分離文字のデフォルト値は改行文字であり、この改行文字によってファイ ルの各行が別々のレコードになります。RS 特殊変数を設定することによって、レコード分離文字を変更することができます。

  3. レコードが、awk コマンドの命令で指定された各パターンと比較されます。

    コマンド命令で、レコードの特定のフィールドを比較するよう指定することができます。 何も指定しないと、フィールドは空白 (ブランクまたはタブ) で区切られます。各フィールドはフィールド変数によって参照されます。 レコードの最初のフィールドには $1 変数、2 番目のフィールドには $2 変数というように、変数が割り当てられます。 レコード全体には $0 変数が割り当てられます。 コマンド・ラインで -F フラグを使用するか、または FS 特殊変数を設定することにより、フィールド分離文字を変更できます。FS 特殊変数は、ブランク、単一文字、または拡張正規表現 のいずれかの値に設定できます。

  4. レコードがあるパターンと一致した場合には、そのパターンに関連付けられたアクションがレコードに対して実行されます。
  5. レコードが各パターンと比較され、指定されたすべてのアクションが実行された後で、次のレコードが入力から読み取られます。この処理は、すべてのレコードが入力ファイルから読み取られるまで繰り返されます。
  6. 複数の入力ファイルが指定された場合には、次のファイルがオープンされます。そして、すべての入力ファイルが読み取られるまで、これが繰り返されます。
  7. 最後のファイルの最後のレコードが読み取られた後で、awk コマンドは、入力処理後に実行するように指定された命令を実行します。

    awk プログラミング言語の END ステートメントで、最後のレコードを読み取った後で実行するアクションを指定できます。 これは、awk コマンドにより実行された処理を示すメッセージを送信するために、特に役立ちます。

awk コマンド・プログラミング言語

awk コマンドのプログラミング言語は、次のフォーマットのステートメントで構成されています。

Pattern { Action }

レコードが指定された Pattern (パターン) と一致するか、またはそのパターンと一致するフィールドを持っている場合には、関連付けられた Action (アクション) が実行されます。 アクションなしでパターンを指定することができます。その場合、そのパターンが入った行全体が標準出力に書き出されます。 パターンなしで指定されたアクションは、すべての入力レコードに対して実行されます。

パターン

awk コマンド言語構文に使用されるパターンは次の 4 種類です。

正規表現

awk コマンドが使用する拡張正規表現は grep コマンドまたは egrep コマンドが使用する拡張正規表現と似ています。拡張正規表現の最も単純なフォーマットは、スラッシュで囲まれた文字の文字列です。 例えば、testfile という名前のファイルが次のような内容を持っているとします。

smawley, andy
smiley, allen
smith, alan
smithern, harry
smithhern, anne
smitters, alexis

ここで、次のコマンド・ラインを入力するとします。

awk '/smi/' testfile

すると、文字列 smi が入っているすべてのレコードが標準出力に出力されます。この例では、awk コマンドのプログラム '/smi/' は、アクションを持たないパターンです。 出力は以下のとおりです。

smiley, allen
smith, alan
smithern, harry
smithhern, anne
smitters, alexis

拡張正規表現は、次の特殊文字を使って形成します。

文字 機能
+ + (正符号) の前の文字または拡張正規表現の 1 個以上のオカレンスが文字列内にある場合、その文字列は一致することを指定します。 コマンド・ラインの例を次に示します。
awk '/smith+ern/' testfile

これは、文字 smit のあとに 1 個または複数の h が続き、ern で終わる文字列が入ったすべてのレコードを、標準出力に出力します。この例の出力は次のようになります。

smithern, harry
smithhern, anne
? (疑問符) の前の文字または拡張正規表現のゼロ個または 1 個のオカレンスが文字列内にある場合、その文字列は一致することを指定します。(疑問符) は文字列の中にあります。コマンド・ラインの例を次に示します。

awk '/smith?/' testfile

これは、smit のあとにゼロ個または 1 個の h 文字が続く文字列が入ったすべてのレコードを標準出力に出力します。この例の出力は次のようになります。

smith, alan
smithern, harry
smithhern, anne
smitters, alexis
| | (縦線) で区切られた文字列のどちらかが文字列内にある場合に、その文字列は一致することを指定します。 コマンド・ライン:
awk '/allen 
| 
alan /' testfile

これは、allen または alan という文字列が入ったすべてのレコードを、標準出力に出力します。この例の出力は次のようになります。

smiley, allen
smith, alan
( ) 文字列を正規表現でグループ化します。 コマンド・ライン:
awk '/a(ll)?(nn)?e/' testfile

これは、ae または alle または anne または allnne という文字列が入ったすべてのレコードを、標準出力に出力します。この例の出力は次のようになります。

smiley, allen
smithhern, anne
{m} パターンのちょうど m 個のオカレンスが文字列内にある場合、その文字列は一致することを指定します。 コマンド・ラインの例を次に示します。

awk '/l{2}/' testfile

これは、標準出力に次のように出力します。

smiley, allen
{m,} パターンの少なくとも m 個のオカレンスが文字列内にある場合、その文字列は一致することを指定します。 コマンド・ラインの例を次に示します。

awk '/t{2,}/' testfile

これは、標準出力に次のように出力します。

smitters, alexis
{m, n} mn の間 (m と n も含む) で、パターンのオカレンスが文字列内にある場合、その文字列は一致することを指定します (m <= n)。 コマンド・ラインの例を次に示します。
awk '/er{1, 2}/' testfile

これは、標準出力に次のように出力します。

smithern, harry
smithern, anne
smitters, alexis
[String] 正規表現が、大括弧内の String 変数で指定された文字と一致することを意味します。 コマンド・ラインの例を次に示します。
awk '/sm[a-h]/' testfile

文字 sm の後にアルファベット順に a から h までの任意の文字が続くすべてのレコードを標準出力に出力します。 この例の出力は次のようになります。

smawley, andy
[^ String] [ ] (大括弧) 内で指定された文字列の先頭にある ^ (脱字記号) は、正規表現が大括弧内のどの文字とも 一致しない ことを示します。 したがって、コマンド・ラインは次のようになります。
awk '/sm[^a-h]/' testfile

これは、標準出力に次のように出力します。


smiley, allen
smith, alan
smithern, harry
smithhern, anne
smitters, alexis
~,!~ 指定された変数が正規表現に一致する (ティルド) か、または一致しない (感嘆符とティルド) かを示す条件ステートメントを表します。コマンド・ラインの例を次に示します。
awk '$1 ~ /n/' testfile

これは、最初のフィールドに文字 n が入ったすべてのレコードを、標準出力に出力します。この例での出力は以下のようになります。

smithern, harry
smithhern, anne
^ フィールドまたはレコードの先頭を示します。 コマンド・ライン:
awk '$2 ~ /^h/' testfile

これは、2 番目のフィールドの最初の文字が h であるすべてのレコードを、標準出力に出力します。この例の出力は次のようになります。

smithern, harry
$ フィールドまたはレコードの終わりを示します。 コマンド・ライン:
awk '$2 ~ /y$/' testfile

これは、2 番目のフィールドの最後の文字が y であるすべてのレコードを、標準出力に出力します。この例の出力は次のようになります。

smawley, andy
smithern, harry
. (ピリオド) スペースの終わりにある、端末の改行文字以外の任意の 1 文字を示します。 コマンド・ラインの例を次に示します。
awk '/a..e/' testfile

これは、a と e の間が 2 文字で分離された文字列を持つすべてのレコードを、標準出力に出力します。この例の出力は次のようになります。


smawley, andy
smiley, allen
smithhern, anne
* (アスタリスク) ゼロ個または 1 個以上の任意の文字を示します。 コマンド・ライン:
awk '/a.*e/' testfile

これは、a と e の間がゼロ個またはそれ以上の文字で分離された文字列を持つすべてのレコードを、標準出力に出力します。この例の出力は次のようになります。

smawley, andy
smiley, allen
smithhern, anne
smitters, alexis
¥ (円記号) エスケープ文字。 拡張正規表現で特別な意味を持つ文字の前にエスケープ文字があると、その文字の特別な意味がなくなります。 例えば、次のコマンド・ラインの例を見てください。
/a¥/¥//

は、パターン a // と一致します。理由は、正規表現の区切り文字としてのスラッシュの通常の意味が、円記号により否定されるからです。 円記号自体を文字として指定するには、円記号を 2 個続けて使用します。 円記号とその使用法の詳細については、このあとのエスケープ・シーケンスの説明を参照してください。

認識されるエスケープ・シーケンス

awk コマンドは、awk コマンド自体が特殊文字として使用する幾つかのエスケープ・シーケンスの他に、C 言語規則で使われるほとんどのエスケープ・シーケンスを認識します。 エスケープ・シーケンスは次のとおりです。

エスケープ・シーケンス 表される文字
¥" ¥" (二重引用符)
¥/ / (スラッシュ) 文字
¥ddd エンコードが 1 桁、2 桁、または 3 桁の 8 進整数で表される文字。d は各桁の 8 進数字を表します。
¥¥ ¥ (円記号)
¥a 警報文字
¥b バックスペース文字
¥f 用紙送り文字
¥n 改行文字 (次の注を参照)
¥r 復帰文字
¥t タブ文字
¥v 垂直タブ

注: gsubmatchsplit、および sub 組み込み関数の場合を除き、拡張正規表現の突き合わせは入力レコードに基づいて行われます。レコード分離文字 (デフォルトでは改行文字) を拡張表現に組み込むことはできず、レコード分離文字に一致する表現はありません。 レコード分離文字が改行文字でない場合は、改行文字の突き合わせができます。 先に述べた 4 つの組み込み関数では、テキスト文字列に基づいて突き合わせが行われるので、任意の文字 (レコード分離文字を含む) をパターンに組み込んで、そのパターンを適切な文字と突き合わせることができます。 ただし、awk コマンドを使用して突き合わせるすべての正規表現では、パターンの中に 1 個以上の NULL 文字が使用されていた場合、結果は予測できません。

関係式

関係演算子 < (より小)、> (より大)、<= (より小か 等しい)、>= (より大か等しい)、= = (等しい)、および ! = (等しくない) を使用して、パターンを 形成できます。例えば、次のパターンを見てください。


$1 < $4

これは、最初のフィールドが 4 番目のフィールドより小さいレコードに一致します。 関係演算子は文字列値と共に使うこともできます。 例えば次のとおりです。


$1 =! "q"

これは、最初のフィールドが q ではないすべてのレコードと一致します。 文字列値を照合値に基づいて突き合わせることもできます。例えば次のとおりです。


$1 >= "d"

これは、最初のフィールドが abc、または d で始まるすべてのレコードと一致します。 これ以上の情報が与えられていなければ、フィールド変数は文字列値として比較されます。

パターンの組み合わせ

次の 3 つのオプションを使用して、パターンを組み合わせることができます。

  • 範囲は , (コンマ) で区切った 2 つのパターンにより指定します。アクションは、最初のパターンと一致するレコードで始まるすべてのレコードに対して実行され、2 番目のパターンと一致するレコードまで (このレコードを含む) 続きます。 例えば次のとおりです。
    /begin/,/end/
    これは、文字列 begin を含むレコード、およびそのレコードから文字列 end を含むレコードまでの間の各レコード (end が入ったレコードを含む) との突き合わせが行われます。
  • 小括弧 ( ) は、パターンをまとめてグループ化します。
  • ブール演算子 || (論理和)、&& (論理積)、および ! (論理否定) は、パターンを組み合わせて、真と評価する場合に一致し、それ以外の場合には一致しない式を形成します。 例えば、次のパターンを見てください。
    
    $1 == "al" && $2 == "123"
    これは、最初のフィールドが al で 2 番目のフィールドが 123 のレコードと一致します。

BEGIN パターンと END パターン

BEGIN パターンで指定したアクションは、入力を読み取る前に実行されます。 END パターンで指定したアクションは、すべての入力を読み取った後で実行されます。 複数の BEGIN パターンと END パターンを指定でき、指定した順序で処理されます。 プログラムのステートメントの中では、END パターンを BEGIN パターンの前に置くことができます。 プログラムが BEGIN ステートメントだけで構成されている場合は、アクションは実行されますが、入力は読み取られません。 プログラムが END ステートメントだけで構成されている場合は、すべてのアクションに先立って入力が読み取られます。

アクション

アクション・ステートメントには、次のように幾つかの種類があります。

アクション・ステートメント

アクション・ステートメントは { } (中括弧) で囲みます。 アクション・ステートメントをパターンなしで指定すると、すべてのレコードに対してアクションが実行されます。 中括弧内に複数のアクションを指定できますが、改行文字または ; (セミコロン) で区切る必要があります。ステートメントは、指定された順に処理されます。 アクション・ステートメントには次のものがあります。

算術ステートメント
算術演算子 + (加算)、- (減算)、/ (除算)、^ (指数)、* (乗算)、% (モジュラス) が、次のフォーマットで使用されます。
Expression Operator Expression

したがって、次のステートメントのようになります。


$2 = $1 ^ 3

これは、最初のフィールドの値の 3 乗を 2 番目のフィールドに割り当てます。

単項ステートメント
単項 - (減算) および単項 + (加算) の働きは、次のように、C プログラミング言語の場合と同様です。
+Expression または -Expression
増分ステートメントと減分ステートメント
前置増分ステートメントと前置減分ステートメントの働きは、次のように、C プログラミング言語の場合と同様です。
++Variable または --Variable

後置増分ステートメントと後置減分ステートメントの働きは、次のように、C プログラミング言語の場合と同様です。

Variable++ または Variable--
代入ステートメント
代入演算子 += (加算)、-= (減算)、/= (除算)、および *= (乗算) は、C プログラミング言語の場合と同様の働きをします。フォーマットは次のとおりです。
Variable += Expression

Variable -= Expression

Variable /= Expression

Variable *= Expression

例えば、次のステートメントがあるとします。

$1 *= $2

これは、フィールド変数 $1 にフィールド変数 $2 を掛けて、新しい値を $1 に割り当てます。

代入演算子 ^= (指数) と %= (モジュラス) は、次のフォーマットになります。

Variable1^=Expression1

かつ

Variable2%=Expression2

これはそれぞれ、C プログラミング言語の次のステートメントと同じです。

Variable1=pow(Variable1, Expression1)

かつ

Variable2=fmod(Variable2, Expression2)

ここで、powpow サブルーチンを示し、 fmodfmod サブルーチンを示します。

文字列連結ステートメント
文字列を並べて書くことにより、文字列値を連結することができます。 例えば次のとおりです。
$3 = $1 $2

これは、フィールド変数 $1$2 内の文字列を連結したものを、フィールド変数 $3 に割り当てます。

組み込み関数

awk コマンド言語は、算術関数、文字列関数、および汎用関数を使用します。 ファイルに書き込んだ後でそのファイルを同じプログラムの中で読み取れるようにするには、close サブルーチン・ステートメントが必要です。

算術関数

次の算術関数は、同じ名前の C 言語のサブルーチンと同じアクションを実行します。

項目 説明
atan2( y, x ) y/x の逆正接を戻します。
cos( x ) x の余弦を戻します。x の単位はラジアンです。
sin( x ) x の正弦を戻します。x の単位はラジアンです。
exp( x ) x の指数関数を戻します。
log( x ) x の自然対数を戻します。
sqrt( x ) x の平方根を戻します。
int( x ) x の値を切り捨てて整数にして戻します。
rand( ) 乱数 n を戻します (0 <= n < 1)。
srand( [Expr ] ) rand 関数のシード値を Expr パラメーターの値に設定します。Expr パラメーターを省略した場合は、時刻が使用されます。 直前のシード値が戻されます。

文字列関数

次のような文字列関数があります。

項目 説明
gsub( Ere, Repl, [ In ] ) 正規表現のすべてのオカレンスを置換することを除いて、sub 関数とまったく同じ演算を実行します。
sub( Ere, Repl, [ In ] ) In パラメーターで指定された文字列の中の Ere パラメーターで指定された拡張正規表現の最初のオカレンスを、Repl パラメーターで指定された文字列で置き換えます。 sub 関数は、置換の数を戻します。 Repl パラメーターで指定された文字列内の & (アンパーサンド) は、Ere パラメーターで指定された拡張正規表現と一致する In パラメーターの中の文字列によって置換されます。 In パラメーターを指定しなかった場合は、デフォルト値としてレコード全体 ($0 レコード変数) が置換されます。
index( String1, String2 ) String1 パラメーターで指定された文字列内部に String2 パラメーターで指定された文字列がある場合に、String1 文字列内での String2 文字列の (1 から数えた) 位置を戻します。 String2 パラメーターが String1 パラメーター内部にない場合は、0 が戻されます。
length [(String)] String パラメーターで指定された文字列の長さ (文字数) を戻します。 String パラメーターを指定しなかった場合は、レコード全体の長さ ($0 レコード変数) が戻されます。
blength [(String)] String パラメーターで指定された文字列の長さ (バイト数) を戻します。 String パラメーターを指定しなかった場合は、レコード全体の長さ ($0 レコード変数) が戻されます。
substr( String, M, [ N ] ) N パラメーターで指定された文字数を持つサブストリングを戻します。 サブストリングは、String パラメーターで指定された文字列から取られ、M パラメーターで指定された位置にある文字で始まっています。 M パラメーターには、String パラメーターの先頭文字を 1 番目の文字として、そこからの番号を指定します。N パラメーターを指定しなかった場合は、サブストリングの長さは、M パラメーターで指定された位置から String パラメーターの終わりまでになります。
match( String, Ere ) Ere パラメーターで指定された拡張正規表現が String パラメーターで指定された文字列内部にあれば、その位置を、先頭文字を 1 とした場合の文字の番号で戻します。Ere パラメーターの値が文字列内にない場合は、0 を戻します。 RSTART 特殊変数は戻り値に設定されます。 RLENGTH 特殊変数は、一致文字列の長さに設定されるか、または、一致する文字列が見つからない場合は -1 (負の 1) に設定されます。
split( String, A, [Ere] ) String パラメーターで指定された文字列を配列エレメント A [1], A [2], .. ., A [n ] に分割し、n 変数の値を戻します。 この分割は、Ere パラメーターで指定された拡張正規表現を使用して行われます。Ere パラメーターを指定しなかった場合は、現行のフィールド分離文字 (FS 特殊変数) を使用して分割されます。 A 配列のエレメントは、特定のエレメントが数値も持つ必要があることがコンテキストにより指示されている場合を除き、文字列値で作成されます。
tolower( String ) String パラメーターで指定された文字列を、文字列内の大文字を小文字に変換して戻します。 大文字と小文字のマッピングは、現行ロケールの LC_CTYPE カテゴリーによって定義されています。
toupper( String ) String パラメーターで指定された文字列を、文字列内の小文字を大文字に変換して戻します。 大文字と小文字のマッピングは、現行ロケールの LC_CTYPE カテゴリーによって定義されています。
sprintf(Format, Expr, Expr, . . . ) Expr パラメーターで指定された表現を、Format パラメーターで指定された printf サブルーチン・フォーマットの文字列に従ってフォーマットし、結果の文字列を戻します。

汎用関数

次のような汎用関数があります。

項目 説明
close( Expression ) print ステートメントまたは printf ステートメントによりオープンされたか、または同じ文字列値の Expression パラメーターを持つ getline 関数への呼び出しによりオープンされたファイルまたはパイプをクローズします。 ファイルまたはパイプが正常にクローズされると、0 が戻されます。クローズに失敗すると、ゼロ以外の値が戻されます。 ファイルに書き込んだ後でそのファイルを同じプログラムの中で読み取るには、close ステートメントが必要です。
system(Command ) Command パラメーターで指定されたコマンドを実行して、その終了状況を戻します。 system サブルーチンと同じです。
Expression | getline [ Variable ] Expression パラメーターで指定されたコマンドの出力からパイプを通して入力されたストリームから、入力レコードを 1 つ読み取って、Variable パラメーターで指定された変数にそのレコードの値を割り当てます。 Expression パラメーターの値と同じ名前のコマンドにより現在オープンされているストリームがない場合は、そのようなストリームが作成されます。 作成されたストリームは、Command パラメーターを Expression パラメーターの値に設定し、Mode パラメーターを値 r に設定して popen サブルーチンを呼び出すことによって作成したストリームと同じです。 ストリームがオープンしたままであって Expression パラメーターの評価結果が同じ文字列になっている限り、このあと getline 関数を呼び出すたびに、レコードが 1 つずつ読み取られます。 Variable パラメーターを指定しなかった場合は、$0 レコード変数と NF 特殊変数の値は、ストリームから読み取られたレコードに設定されます。
getline [ Variable ] < Expression Expression パラメーターで指定されたファイルから次の入力レコードを 1 つ読み取って、Variable パラメーターで指定された変数の値をそのレコードの値に設定します。ストリームがオープンしたままであって Expression パラメーターの評価結果が同じ文字列になっている限り、このあと getline 関数を呼び出すたびに、レコードが 1 つずつ読み取られます。 Variable パラメーターを指定しなかった場合は、$0 レコード変数と NF 特殊変数の値は、ストリームから読み取られたレコードに設定されます。
getline [ Variable ] Variable パラメーターで指定された変数の値を、現行の入力ファイルから取り出した次の入力レコードに設定します。 Variable パラメーターを指定しなかった場合は、$0 レコード変数の値は、入力レコードの値に設定され、NFNR、および FNR の各特殊変数も同様に設定されます。

注: どのフォーマットの getline 関数も、正常な入力の場合は 1 を戻し、ファイルの終わり (EOF) の場合は 0 を戻し、エラーの場合は -1 を戻します。

ユーザー定義関数

ユーザー定義関数は、次のフォーマットで宣言します。

function Name (Parameter, Parameter,...)  { Statements }

関数は、awk コマンド・プログラム内のどこからでも参照でき、関数定義の前でも使用できます。 関数の有効範囲はグローバルです。

関数パラメーターは、スカラーまたは配列のどちらかにできます。 パラメーター名だけは関数にとってローカルなものですが、その他のすべての変数名はグローバルです。 異なるエンティティーに同じ名前を使用することはできません。例えば、パラメーター名を、関数名または特殊変数として重複使用することはできません。グローバルな有効範囲を持つ変数は、関数と同じ名前を共用することはできません。 スカラーと配列は、同じ有効範囲内で同じ名前を持つことはできません。

関数定義の中のパラメーターの数は、関数を呼び出すときに使用されるパラメーターの数と一致していなくてもかまいません。 余分な仮パラメーターはローカル変数として使用できます。 余分なスカラー・パラメーターは、空文字列と等価の文字列値および数値 0 を使用して初期化されます。余分な配列パラメーターは空配列として初期化されます。

関数を呼び出す場合、関数名と左括弧の間にはホワイト・スペースを入れません。 関数呼び出しはネストでき、再帰的です。 ネストされた関数呼び出しまたは再帰的関数呼び出しから戻ったとき、すべての呼び出し元関数のパラメーターの値は、参照により渡された配列パラメーターを除き、すべて元の状態のままでなければなりません。 return ステートメントを使用して値を戻すことができます。

関数定義内部では、改行文字は { (左中括弧) の前と、} (右中括弧) の後に、入れても入れなくてもかまいません。

関数定義の例を次に示します。


function average ( g,n) 
  {
        for (i in g)
           sum=sum+g[i]
        avg=sum/n
        return avg
  } 

関数 average には、配列 g と変数 n が、配列内のエレメントの数と共に渡されます。次に、この関数は平均を取得し、その値を戻します。

条件ステートメント

awk コマンド・プログラミング言語のほとんどの条件ステートメントは、C プログラミング言語の条件ステートメントの構文および機能と同じです。 どの条件ステートメントでも、{ } (中括弧) を使ってステートメントをグループ化できます。 条件ステートメントの式の部分とステートメント部分の間には改行文字を入れても入れなくてもかまいません。また、{ } (中括弧) 内の複数のステートメントを区切るには、改行文字または ; (セミコロン) を使用します。 C 言語型の 6 つの条件ステートメントは次のとおりです。

項目 説明
if 構文は次のとおりです。

if ( Expression ) { Statement } [ else Action ]

while 構文は次のとおりです。

while ( Expression ) { Statement }

for 構文は次のとおりです。

for ( Expression ; Expression ; Expression) { Statement }

break break ステートメントを while ステートメントまたは for ステートメント内で使用すると、プログラム・ループが終了します。
continue continue ステートメントを while ステートメントまたは for ステートメント内で使用すると、プログラム・ループが次の反復に進みます。

awk コマンド・プログラミング言語には C 言語の規則に従わない、次の 5 つの条件ステートメントがあります。

項目 説明
for...in 構文は次のとおりです。

for ( Variable in Array ) { Statement }

for...in ステートメントは、Variable パラメーターを、一度に 1 索引ずつ順不同で Array 変数の各索引値に設定し、反復するたびに、Statement パラメーターで指定されたアクションを実行します。 for...in ステートメントの例については、delete ステートメントを参照してください。

if...in 構文は次のとおりです。

if ( Variable in Array ) { Statement }

if...in ステートメントは、Array エレメントが存在するかどうかを調べます。 Array エレメントが見つかると、ステートメントが実行されます。

delete 構文は次のとおりです。

delete Array [ Expression ]

delete ステートメントは、Array パラメーターで指定された配列エレメントと Expression パラメーターで指定された索引の両方を削除します。 例えば、次のステートメントを見てください。


for (i in g)
   delete g[i];

これは、g[] 配列のすべてのエレメントを削除します。

exit 構文は次のとおりです。

exit [Expression]

exit ステートメントは、まず最初にすべての END アクションを発生順に呼び出し、次に、Expression パラメーターで指定された終了状況で awk コマンドを終了させます。 exit ステートメントが END アクション内部で発生すると、それ以上の END アクションは呼び出されません。

# 構文は次のとおりです。

# Comment

# ステートメントは注釈を入れます。 注釈は、必ず改行文字で終わらせる必要がありますが、行のどこからでも始めることができます。

next 現行の入力レコードの処理を停止して、次の入力レコードに進みます。

出力ステートメント

awk コマンド・プログラミング言語の 2 つの出力ステートメントは次のとおりです。

項目 説明
print 構文は次のとおりです。

print [ ExpressionList ] [ Redirection ] [ Expression ]

print ステートメントは、ExpressionList パラメーターで指定された各式の値を、標準出力に書き出します。 各式は OFS 特殊変数の現行値によって分離され、各レコードは ORS 特殊変数の現行値によって終了します。

出力は、Redirection パラメーターを 使用してリダイレクトできます。このパラメーターでは、> (より大)、>> (二重の より大)、および | (パイプ) によって、3 つの出力リダイレクトが指定 できます。Redirection パラメーターでは、出力をリダイレクトする方法を 指定し、Expression パラメーターは、ファイルへの パス名 (Redirection パラメーターが > または >> のとき) と コマンドの名前 (Redirection パラメーターが | のとき) のいずれかです。

printf 構文は次のとおりです。

printf Format [ , ExpressionList ] [ Redirection ] [ Expression ]

printf ステートメントは、ExpressionList パラメーターで指定された式を、Format パラメーターで指定されたフォーマットで標準出力に書き出します。 printf ステートメントの機能は、c 変換仕様 (%c) を除いて、 printf コマンドとまったく同じです。 Redirection パラメーターおよび Expression パラメーターの機能は、print ステートメントの場合と同じです。

c 変換仕様の場合: 引数が数値の場合は、その値をエンコードに持つ文字が出力されます。値が 0 であるか、または文字セットのどの文字のエンコードにも対応していない場合は、動作は不定です。 引数が数値でない場合は、文字列値の先頭文字が出力されます。文字列内に文字がまったく含まれていない場合の動作は不定です。

注: Expression パラメーターに Redirection パラメーター用のパス名を指定する場合は、Expression が必ず文字列として処理されるように、そのパラメーターを二重引用符で囲む必要があります。

変数

変数は、スカラー、フィールド変数、配列、または特殊変数のどれかです。 変数名の先頭に数字を使用することはできません。

変数は、変数を参照するだけで使用できます。 関数パラメーターを除き、変数は明示的には宣言されません。 初期化されていないスカラー変数と配列エレメントは、数値 0 と null 文字列 (" ") の文字列値の両方を持っています。

変数は、コンテキストに従って、数値または文字列値をとります。 各変数は、数値、文字列値、またはこの両方を持つことができます。 例えば次のとおりです。


x = "4" + "8"

これは、値 12 を変数 x に割り当てます。 文字列定数の場合は、式を " " (二重引用符) で囲む必要があります。

数字と文字列の間の明示的な変換はありません。 強制的に式を数値として処理するには、式に 0 を追加します。 式を文字列として処理するには、末尾に null 文字列 (" ") を追加します。

フィールド変数

フィールド変数は、$ (ドル記号) とそれに続く数値または数値式で指定します。 レコードの最初のフィールドに $1 変数、2 番目のフィールドに $2 変数というように、順に割り当てられます。 $0 フィールド変数はレコード全体に割り当てられます。 値を割り当てることによって、新しいフィールド変数を作成できます。 存在しないフィールド、つまり $NF フィールド変数の値より現行値が大きいフィールドに値を割り当てると、中間フィールドが (null 文字列に設定されて) 自動的に作成され、NF 特殊変数の値が増加し、$0 レコード変数の値が自動的に再計算されます。 新規フィールドは、現行のフィールド分離文字 (つまり FS 特殊変数の値) で区切られます。 デフォルトのフィールド分離文字はブランクおよびタブです。 フィールド分離文字を変更するには、-F フラグを使用するか、または awk コマンド・プログラムの中で FS 特殊変数に別の値を割り当てます。

配列

配列は、最初は空であり、サイズが動的に変化します。 配列は、[ ] (大括弧) で囲んだ添え字を持つ変数によって表されます。 添え字つまりエレメント ID は、文字列の数字であり、結合配列の機能のタイプを示します。 例えば、次のプログラムを見てください。

/red/  { x["red"]++ }
/green/ { y["green"]++ }

これは、red カウンターと green カウンターの両方のカウントを増分します。

配列は、幾つかのプログラミング言語の多次元配列と同様に、2 つ以上の添え字を使って索引付けできます。 awk コマンドのプログラミング配列は現実に 1 次元なので、コンマで区切られた添え字は、別の式の文字列値を連結し各式を SUBSEP 環境変数の値によって区切った、単一の文字列に変換されます。 したがって、次の 2 つの索引操作は同じです。


x[expr1, expr2,...exprn]

かつ

x[expr1SUBSEPexpr2SUBSEP...SUBSEPexprn]

in 演算子を使用するときは、多次元の Index 値は括弧で囲む必要があります。 in 演算子の場合を除き、存在しない配列エレメントを参照すると、そのエレメントが自動的に作成されます。

特殊変数

次の変数は、awk コマンドの場合は特別な意味になります。

項目 説明
ARGC ARGV 配列内のエレメント数。 この値は変更できます。
ARGV 各メンバーに File 変数または Assignment 変数の 1 つが入っている配列。これらの変数は、コマンド・ラインから順に取り込まれ、0 から ARGC -1 までの番号が付きます。 各入力ファイルが終了すると、ARGV 配列の次のメンバーが次の入力ファイルの名前を与えます。ただし、次の場合を除きます。
  • 次のメンバーが Assignment ステートメントの場合。この場合は、代入値を使って評価されます。
  • 次のメンバーが null 値の場合。この場合、そのメンバーはスキップされます。 ARGV 配列内の選択済み入力ファイルが入ったメンバーを null 値に設定することによって、プログラムでその入力ファイルをスキップすることができます。
  • 次のメンバーが ARGV [ARGC -1] の現行値である場合。awk コマンドは、この値を入力ファイルの終わりと解釈します。
CONVFMT 数字を文字列に変換する printf 構文 (OFMT 特殊変数を使用する出力ステートメントを除く)。 デフォルトは "% .6g" です。
ENVIRON awk コマンドの操作環境を表す配列。 この配列の各エレメントは次のフォーマットになります。

ENVIRON [ "Environment VariableName" ] = EnvironmentVariableValue

awk コマンドが実行を開始すると値が設定され、 ENVIRON 特殊変数が途中で変更されてもそれに関係なく、実行が終わるまでは同じ環境が使用されます。

FILENAME 現行の入力ファイルのパス名。 BEGIN アクションの実行中は、FILENAME の値は未定義です。 END アクションの実行中は、この値は最後に処理された入力ファイルの名前になります。
FNR 現行ファイル内の現行入力レコードの数。
FS 入力フィールド分離文字。デフォルト値はブランクです。 入力フィールド分離文字がブランクの場合には、ロケール定義のスペースをいくつでも使ってフィールドを分離できます。 FS 特殊変数は、このほかに次の 2 つの値をとることができます。
  • FS を単一の文字に設定すると、その文字が 1 つあるたびにフィールドが分離されます。
  • FS拡張正規表現に設定すると、その拡張正規表現と一致するシーケンスがあるたびにフィールドが分離されます。
NF 現行レコード内のフィールド数 (最大 99)。 BEGIN アクション内では、Variable パラメーターなしの getline 関数が事前に発行されている場合を除いて、NF 特殊変数は未定義です。 Variable パラメーターなしの後続のリダイレクトされた getline 関数が END アクションに入る前に発行されている場合を除いて、その END アクション内では、NF 特殊変数は、最後に読み取ったレコードのフィールド数をそのまま保存しています。
NR 現行の入力レコードの番号。 BEGIN アクション内では、NR 特殊変数の値は 0 です。 END アクション内では、この値は最後に処理されたレコードの番号です。
OFMT 出力ステートメント内で数字を文字列に変換する printf 構文。 デフォルトは "%.6g" です。
OFS 出力フィールド分離文字 (デフォルトはスペース)。
ORS 出力レコード分離文字 (デフォルトは改行文字)。
RLENGTH match 関数で一致した文字列の長さ。
RS 入力レコード分離文字 (デフォルトは改行文字)。 RS 特殊変数が null の場合は、レコードは 1 つ以上のブランク行のシーケンスで分離されます。 先頭または末尾のブランク行が、入力の始めまたは終わりで空のレコードになることはありません。 また、FS 特殊変数の値にかかわらず、改行文字は常にフィールド分離文字です。
RSTART match 関数で一致した文字列の開始位置 (起点は 1)。match 関数の戻り値と同じです。
SUBSEP 複数の添え字を分離します。 デフォルトは ¥031 です。

フラグ

項目 説明
-f ProgramFile ProgramFile 変数で指定されたファイルから、awk コマンド用の命令を取得します。 -f フラグを複数回指定すると、ファイルを指定順に連結したものが命令セットとして使用されます。
-u バッファーなしモードで出力を表示します。このフラグが使用された場合、awk コマンドは出力をバッファーに入れません。代わりに、出力を即座に表示します。デフォルトでは、awk コマンドはバッファー付きモードで出力を表示します。
-F Ere Ere 変数で指定された拡張正規表現がフィールド分離文字として使用されます。 デフォルトのフィールド分離文字はブランクです。
-v Assignment awk コマンドのプログラミング言語の変数に値を割り当てます。 Assignment パラメーターのフォーマットは Name = Value です。 Name 部分は変数名を示し、下線、数字、および英字を自由に組み合わせて指定できますが、先頭は英字または下線でなければなりません。 Value 部分も、下線、数字、および英字で構成され、文字列値と同様に、前後を " (二重引用符) で囲まれているものとして取り扱われます。 Value 部分が数値の場合は、変数にもその数値が割り当てられます。

-v フラグで指定された割り当ては、BEGIN セクションを含めて、awk コマンドのプログラムのどの部分もまだ実行されないうちに行われます。

Assignment awk コマンドのプログラミング言語の変数に値を割り当てます。 フォーマットと機能は、処理時点が異なることを除いて、-v フラグを指定した Assignment 変数と同じです。 Assignment パラメーターは、コマンド・ラインでこのパラメーターのあとに続く入力ファイル (File 変数で指定されたもの) の直前に処理されます。 複数の入力ファイルの先頭ファイルの直前に Assignment パラメーターを指定した場合は、割り当ては BEGIN セクション (もしあれば) の直後に処理されます。 Assignment パラメーターが最後のファイルのあとにある場合は、割り当ては END セクション (もしあれば) の前に処理されます。 入力ファイルを指定しなければ、割り当ては標準入力の読み取り時に処理されます。
File 処理用の入力が入っているファイルの名前を指定します。 File 変数を指定しなかった場合、または - (負) 符号を指定した場合は、標準入力が処理されます。
'Program' awk コマンド用の命令が入っています。 -f フラグを指定しない場合は、Program 変数がコマンド・ラインの最初の項目でなければなりません。 また、' ' (単一引用符) で囲む必要があります。

終了状況

このコマンドは次の終了値を戻します。

項目 説明
0 正常終了。
>0 エラーが発生しました。

exit [ Expression ] 条件ステートメントを使って、プログラム内の終了状況を変更できます。

  1. ファイルの中にある 73 文字以上の行を表示するには、次のように入力します。
    awk  'length  >72'  chapter1
    これは、72 文字を超える長さの個々の行を chapter1 ファイルから選択し、Action が特に指定されていないので、それらの行を標準出力に書き出します。タブ文字は 1 バイトとして計算されます。
  2. startstop という単語の間にあるすべての行を、「start」と「stop」のある行も含めて表示するには、次のように入力します。
    awk  '/start/,/stop/'  chapter1
  3. ファイル chapter1 を処理する awk コマンド・プログラム sum2.awk を実行するには、次のように入力します。
    awk  -f  sum2.awk  chapter1
    次のプログラム sum2.awk は、入力ファイル chapter1 の 2 列目の数値の合計と平均を計算します。
        {
           sum += $2
        }
    END {
           print "Sum: ", sum;
           print "Average:", sum/NR;
        }
    最初のアクションでは、各行の 2 番目のフィールドの値が加算され、変数 sum に入れられます。変数はすべて、最初に参照される時点で数値 0 に初期化されます。 2 番目のアクションの前にパターン END があるので、2 番目のアクションはすべての入力ファイルの読み取りが終わってから実行されます。 NR 特殊変数は、平均計算に使用されるもので、読み取られたレコード数を示します。
  4. 最初の 2 つのフィールドを逆の順序で表示するには、次のように入力します。
    awk '{ print $2, $1 }' chapter1
  5. awk プログラムを以下に示します。
    awk -f sum3.awk chapter2
    これは、ファイル chapter2 の最初の 2 つのフィールドを表示します。 このとき、入力フィールドをコンマまたはブランク (あるいはその両方) とタブで区切り、最初の列の合計を出し、その合計と平均を表示します。
    BEGIN  {FS = ",|[ ¥t]+"}
           {print $1, $2}
           {s += $1}
    END    {print "sum is",s,"average is", s/NR }