awkの結果を別のコマンドのパラメータとして使用する

awkの結果を別のコマンドのパラメータとして使用する

awk を使用して一連のテキスト ファイルから行を抽出しています。ファイルは次のようになります。

1000    1    75
1000    2    76
1001    1    76
1001    2    80

次のコマンドを使用して、これらのディレクトリをいくつか検索します。

awk -F"\t" '$3 == "76" { print $1"\t"$2}' ../benchmark/*/labels.txt

awk は正しい出力を出力します:

1000    2
1001    1

ここで、見つかった行ごとに、次のように、これらの 2 つの数値をパラメーターとして渡すスクリプトを実行する必要があります。

./build.oct 1000    2

正しい方法は何ですか? スクリプト コンソールの出力についてはあまり気にしません (ファイルが生成されます)。

答え1

xargs(を使用-lすると、行ごとに個別のコマンドが実行されます)を使用することもできます。

timp@helez:~/tmp$ awk -F"\t" '$3 == "76" { print $1"\t"$2}' test.txt | xargs -l ./build.oct 
$1 is  1000  and $2 is  2
$1 is  1001  and $2 is  1

timp@helez:~/tmp$ cat test.txt
1000    1   75
1000    2   76
1001    1   76
1001    2   80
timp@helez:~/tmp$ cat build.oct
echo '$1 is ' $1 ' and $2 is ' $2

コメントで示唆されているように、とはタブとスペースの両方で分割されるawkため、コマンドを簡略化することもできます。awkxargs

timp@helez:~/tmp$ awk '$3 == "76" {print $1,$2}' test.txt | xargs -l ./build.oct
$1 is  1000  and $2 is  2
$1 is  1001  and $2 is  1

答え2

これは私にとってはうまくいきました:

awk -F"\t" '$3 == "76" { printf "./build.oct %d %d\n", $1, $2}' \
../benchmark/*/labels.txt | bash

答え3

このことを考慮:

cat ../benchmark/*/labels.txt |
while IFS=$'\t' read P1 P2 P3 ; do
  [[ $P3 == 76 ]] && echo $P1 $P2
done |
sort -u |
parallel ./build.oct
  • 組み込みパーサーをawk使用してサブプロセスを保存します(以下のコメントを参照)readline
  • 騙されないようにするにはsort -u
  • parallel (またはxargs -l1)を使用してリソースの使用率を高める

その他の興味深いアプローチは、以下によって試行されていますawk:

awk -F'\t' '$3==76 && !seen[$1,$2]++ {
  print $1 FS $2 | "parallel ./build.oct"
}' ../benchmark/*/labels.txt
  • FSリテラルの代わりに入力フィールドセパレーターを再利用します
  • 重複はカウンターの配列を使用して破棄されます
  • awkサブプロセスへのパイプ処理を学ぶ

答え4

Gnu awkにはsystem関数があります。次のようなものを実行できます。

awk '$3 == "76" { system("./build.oct " $1 " " $2) }' ....

関連情報