Estou extraindo linhas de um conjunto de arquivos de texto com o awk. Os arquivos ficam assim:
1000 1 75
1000 2 76
1001 1 76
1001 2 80
Estou pesquisando vários diretórios destes com este comando:
awk -F"\t" '$3 == "76" { print $1"\t"$2}' ../benchmark/*/labels.txt
awk está me dando a saída correta:
1000 2
1001 1
Agora para cada linha encontrada devo executar um script passando esses dois números como parâmetros, assim:
./build.oct 1000 2
Qual é a maneira correta de fazer isso? Eu realmente não me importo com a saída do console de script (ela produz arquivos).
Responder1
Você também pode usar xargs
( -l
faz executar um comando separado para cada linha):
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
Conforme sugerido nos comentários você também pode simplificar o awk
comando, já que ambos awk
são xargs
divididos em tabulações e espaços:
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
Responder2
Isso funcionou para mim:
awk -F"\t" '$3 == "76" { printf "./build.oct %d %d\n", $1, $2}' \
../benchmark/*/labels.txt | bash
Responder3
Considere isto:
cat ../benchmark/*/labels.txt |
while IFS=$'\t' read P1 P2 P3 ; do
[[ $P3 == 76 ]] && echo $P1 $P2
done |
sort -u |
parallel ./build.oct
- você salva
awk
o subprocesso comreadline
o analisador integrado (veja os comentários abaixo) - você evita idiotas com
sort -u
- você aproveita o uso de recursos com
parallel
(ouxargs -l1
)
Outra abordagem de interesse, pilotada por awk
:
awk -F'\t' '$3==76 && !seen[$1,$2]++ {
print $1 FS $2 | "parallel ./build.oct"
}' ../benchmark/*/labels.txt
- reutilizar separador de campo de entrada
FS
em vez de literal - ingênuos são descartados usando uma série de contadores
- você aprende a canalizar para o subprocesso awk
Responder4
Gnu awk tem uma system
função. Você poderia executar algo nos moldes de
awk '$3 == "76" { system("./build.oct " $1 " " $2) }' ....