システムコール、AWK、外部入力の導入

システムコール、AWK、外部入力の導入
awk '{ TEMPVAR="/usr/bin"; printf("%s", system("ls $TEMPVAR")); }' empty

TEMPVARこの例では、呼び出しに変数を導入しようとしていますsystem。どうすればいいですか?

私の目標は次のとおりです。ファイルの各行で発生する呼び出しを使用しようとしていますdate -d $0 +%s。しかし、その値をシステムコールにsystem入れるのに苦労しています。$0

答え1

awkENVIRON環境変数は特別な配列を使用してアクセスできます。ただし、配列要素に値を割り当てることはできますが、awk'ssystemまたは| getline実行されたコマンドのコンテキストでは渡されませんprint |。この配列は、次の目的にのみENVIRON使用されます。awk得る渡す環境変数の値です。

を実行できますが、system("ls " var)(またはまたは)に渡された文字列は実際に引数として渡されるため、シェルコードとして解釈されます。awksystem()print || getlinesh -c

たとえば、awk var変数にが含まれている場合は、呼び出されたファイルを一覧表示するのではfoo;rm -rf /なく、呼び出されたファイルを一覧表示してからコマンドを実行するように指示します。ls"foo;rm -rf /"foorm

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)))

源泉

関連情報