Использовать результаты 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

Теперь для каждой найденной строки я должен выполнить скрипт, передавая эти два числа в качестве параметров, например так:

./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) }' ....

Связанный контент