Use os resultados do awk como parâmetros para outro comando

Use os resultados do awk como parâmetros para outro comando

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( -lfaz 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 awkcomando, já que ambos awksão xargsdivididos 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 awko subprocesso com readlineo analisador integrado (veja os comentários abaixo)
  • você evita idiotas comsort -u
  • você aproveita o uso de recursos com parallel (ou xargs -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 FSem 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 systemfunção. Você poderia executar algo nos moldes de

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

informação relacionada