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
ため、コマンドを簡略化することもできます。awk
xargs
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) }' ....