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
xargs
Sie können auch ( -l
bewirkt, 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 awk
Befehl auch vereinfachen, da sowohl bei Tabulatoren als awk
auch xargs
bei 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
awk
Unterprozesse mitreadline
integriertem Parser (siehe Kommentare unten) - Sie vermeiden Duplikate mit
sort -u
- Sie nutzen die Ressourcennutzung mit
parallel
(oderxargs -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
FS
anstelle des Literals - Duplikate werden mithilfe einer Reihe von Zählern verworfen
- Sie lernen das Weiterleiten an den awk-Unterprozess
Antwort4
Gnu awk hat eine system
Funktion. Sie könnten etwas in der Art von
awk '$3 == "76" { system("./build.oct " $1 " " $2) }' ....