awk '{ TEMPVAR="/usr/bin"; printf("%s", system("ls $TEMPVAR")); }' empty
TEMPVAR
この例では、呼び出しに変数を導入しようとしていますsystem
。どうすればいいですか?
私の目標は次のとおりです。ファイルの各行で発生する呼び出しを使用しようとしていますdate -d $0 +%s
。しかし、その値をシステムコールにsystem
入れるのに苦労しています。$0
答え1
awk
ENVIRON
環境変数は特別な配列を使用してアクセスできます。ただし、配列要素に値を割り当てることはできますが、awk
'ssystem
または| getline
実行されたコマンドのコンテキストでは渡されませんprint |
。この配列は、次の目的にのみENVIRON
使用されます。awk
得る渡す環境変数の値です。
を実行できますが、system("ls " var)
(またはまたは)に渡された文字列は実際に引数として渡されるため、シェルコードとして解釈されます。awk
system()
print |
| getline
sh -c
たとえば、awk
var
変数にが含まれている場合は、呼び出されたファイルを一覧表示するのではfoo;rm -rf /
なく、呼び出されたファイルを一覧表示してからコマンドを実行するように指示します。ls
"foo;rm -rf /"
foo
rm
var
したがって、変数のシェル固有の文字をエスケープする必要があるかもしれません。
たとえば、次のようにできます。
awk '
function escape(s) {
gsub(/'\''/, "&\\\\&&", s)
return "'\''" s "'\''"
}
{
cmd = "date -d " escape($0) " +%s"
cmd | getline seconds
close(cmd)
print seconds
}'
これは、1行に1つのシェルと1つのコマンドを実行することを意味しますがdate
、シェル自体を使用してファイルを読み取ることもできます。
while IFS= read <&3 -r line; do
date -d "$line" +%s
done 3< the-file
答え2
Awk変数を渡すとシステム、引用するにはシェルが必要です。
function quote(str, d, m, x, y, z) {
d = "\47"; m = split(str, x, d)
for (y in x) z = z d x[y] d (y < m ? "\\" d : "")
return z
}
例:
system(sprintf("date -d %s +%%s", quote($0)))