Я извлекаю строки из набора текстовых файлов с помощью 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) }' ....