Verwenden Sie Awk-Ergebnisse als Parameter für einen anderen Befehl

Verwenden Sie Awk-Ergebnisse als Parameter für einen anderen Befehl

Ich extrahiere Zeilen aus einer Reihe von Textdateien mit awk. Die Dateien sehen folgendermaßen aus:

1000    1    75
1000    2    76
1001    1    76
1001    2    80

Ich durchsuche mehrere Verzeichnisse davon mit diesem Befehl:

awk -F"\t" '$3 == "76" { print $1"\t"$2}' ../benchmark/*/labels.txt

awk gibt mir die richtige Ausgabe:

1000    2
1001    1

Jetzt muss ich für jede gefundene Zeile ein Skript ausführen, das diese beiden Zahlen als Parameter übergibt, etwa so:

./build.oct 1000    2

Wie geht das richtig? Die Ausgabe der Skriptkonsole interessiert mich nicht wirklich (sie erzeugt Dateien).

Antwort1

xargsSie können auch ( -lbewirkt, dass für jede Zeile ein separater Befehl ausgeführt wird) verwenden :

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

Wie in den Kommentaren vorgeschlagen, können Sie den awkBefehl auch vereinfachen, da sowohl bei Tabulatoren als awkauch xargsbei Leerzeichen geteilt wird:

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

Antwort2

Das hat bei mir funktioniert:

awk -F"\t" '$3 == "76" { printf "./build.oct %d %d\n", $1, $2}' \
../benchmark/*/labels.txt | bash

Antwort3

Bedenken Sie:

cat ../benchmark/*/labels.txt |
while IFS=$'\t' read P1 P2 P3 ; do
  [[ $P3 == 76 ]] && echo $P1 $P2
done |
sort -u |
parallel ./build.oct
  • Sie speichern awkUnterprozesse mit readlineintegriertem Parser (siehe Kommentare unten)
  • Sie vermeiden Duplikate mitsort -u
  • Sie nutzen die Ressourcennutzung mit parallel (oder xargs -l1)

Ein weiterer interessanter Ansatz, der erprobt wurde von awk:

awk -F'\t' '$3==76 && !seen[$1,$2]++ {
  print $1 FS $2 | "parallel ./build.oct"
}' ../benchmark/*/labels.txt
  • Wiederverwendung des Eingabefeldtrennzeichens FSanstelle des Literals
  • Duplikate werden mithilfe einer Reihe von Zählern verworfen
  • Sie lernen das Weiterleiten an den awk-Unterprozess

Antwort4

Gnu awk hat eine systemFunktion. Sie könnten etwas in der Art von

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

verwandte Informationen