EnvVarGeneralJapanese

環境変数を使う

解答 1:

Unix では「もうひとつのクォート」を使います。例えば、以下のようなものです。

        awk -F: '$1 ~ /'"$USER"'/ {print $5}' /etc/passwd
                ^^^^^^^^*******^^^^^^^^^^^^^^

例えば、標準的な Unix のシェルでは上のアンダーラインの部分は (スペースも込みで) awk にひとつの長い引数として送られます。

        $1 ~ /bwk/ {print $5}

クォートされた部分の間のスペースはないかもしれないことに注意してください。一方、シングルクォートで括らない場合には、Unix のシェルは引数をスペースで分割してしまうため、(上の例のように `\' や '' で括ったり "" で括ったりしない限りは) 長いスクリプトの引数となります。

使っている awk のバージョン (この場合にはアップグレードするべきですが、このためだけというわけではありません) によってサポートされている場合以外では、この方法は一般的に避けた方が良いです。 一般的に信頼されていないという問題であり、その結果は使おうとしている実際のシェルの変数の内容に大きく左右されてしまいます。 (comp.lang.awk で議論されている) いくつかの例を上げておきます。

$ var="#"
$ awk 'BEGIN{ print '"$var"' }'
awk: cmd. line:1: BEGIN{ print # }
awk: cmd. line:1:              ^ syntax error

上の例は awk プログラムの中でダブルクォートとして使用しているものとして「訂正」されてしまうかもしれません。

$ var="#"
$ awk 'BEGIN{ print "'"$var"'" }'
#

しかしながら、これで十分というわけではありません。

$ var="hello
world"
$ awk 'BEGIN{ print "'"$var"'" }'
awk: BEGIN{ print "hello
awk:              ^ unterminated string

そこで -v を使うと動作させることができます。

$ var="hello
world"
$ awk -v var="$var" 'BEGIN{ print var }'
hello
world 

次に -v を使った解答を見ていきましょう。

解答 2:

自分の awk がコマンドラインでの変数定義をサポートしているかどうかを知るにはマニュアルを読んでください。 例えば、以下のようなものです。

  awk -F: -v name="$USER" '$1 ~ name {print $5}' /etc/passwd

解答 3

自分の awk が環境変数にアクセスできるかどうかはマニュアルを読んでください。 多分、以下のようにすれば分かるでしょう。

  awk -F: '$1 ~ ENVIRON["USER"] {print $5}' /etc/passwd

ひとつのコマンドで環境変数を簡単に /bin/sh スクリプトで扱えることを覚えておくと便利でしょう。

        name=felix age=56 awk '... ENVIRON["name"] .....'

これは ksh でも他のいくつかのシェルでも動作します。

最初の方法は可搬性がありますが、awk で "-f" でスクリプトファイルを指定した場合には動作しません。 こうした場合にはシェルスクリプトを使い、必要であれば長い '...' という部分の awk コマンド引数を複数行に分けると良いでしょう。

/bin/csh は行の折り返しに \ が必要ですが、/bin/sh では不要ということも注意しましょう。

awk でシェルの変数の値を使うことを非常に深く議論したものは [1] を参照してください。