Ist es eine gute Idee, die Eingabe zu filtern, bevor die Awk-Aktion ausgeführt wird?

Ist es eine gute Idee, die Eingabe zu filtern, bevor die Awk-Aktion ausgeführt wird?

Wenn ich Eingaben habe, ist es dann besser, die Daten zu filtern, bevor ich meine awkAktion ausführe, oder sollte ich die gesamte Filterung durchführen awk?

Nehmen wir beispielsweise die folgende Eingabe an:

$ echo "foo\nbar\nbaz"
foo
bar
baz

Soll ich ausführen:

$ echo "foo\nbar\nbaz" | sed 1q | awk '{ print $0 " cats" }'
foo cats

Oder:

$ echo "foo\nbar\nbaz" | awk 'NR == 1 { print $0 " cats" }'
foo cats
  • Warum sollte ich eines von beiden ausführen?
  • Sollte ich ein anderes Werkzeug verwenden?
  • Welche Faktoren sollte ich berücksichtigen?
  • Wie kann ich diese Faktoren testen?

Antwort1

In diesem konkreten Fall ist die zweite Option die bessere.

Im Allgemeinen ist es effizienter, die Anzahl der Dienstprogramme in einer Pipeline zu minimieren. Es ist am besten, unnötige Prozesse nicht zu forken (starten) (wie in Ihrem ersten Beispiel mit einem unnötigen sedProzess). Im Internet findet man leicht Beispiele für Beschwerden übernutzlose Verwendungen von Katzen.

Bei den meisten modernen Unix-ähnlichen Systemen * wird das Forking recht effizient durchgeführt, es hängt jedoch von der Größe des zu startenden Prozesses ab; beispielsweise wäre das Starten von perloder viel langsamer als das Starten von oder .pythonsedawk

Bei einmaligen Befehlen spielt dies keine so große Rolle. Wenn sich Ihre Pipeline jedoch in einer Schleife befindet und viele Male ausgeführt wird, kann das Entfernen unnötiger Prozesse aus Ihrer Pipeline die Gesamtausführungszeit erheblich verkürzen.

Spezifische Fragen

Warum sollte ich eines von beiden ausführen?

Wenn Sie mit der Syntax des einen besser vertraut sind als mit der des anderen, ist es für die Lesbarkeit (und Wartbarkeit) des Codes möglicherweise besser, das Tool/die Sprache zu verwenden, mit der Sie am besten vertraut sind.

Sollte ich ein anderes Werkzeug verwenden?

In diesem konkreten Fall würde ich das nicht glauben. Sowohl als awkauch sedsind geeignete Werkzeuge für diese Art von Arbeit.

Welche Faktoren sollte ich berücksichtigen?

Wenn Sie mehrere Dateien verarbeiten müssen (z. B. in einer Schleife), ist Geschwindigkeit/Effizienz wichtig.

Wenn Sie nur ab und zu eine große Datei verarbeiten, ist die Lesbarkeit des Codes möglicherweise wichtiger.

Wie kann ich diese Faktoren testen?

Sie können verschiedene Versionen mit dem timeDienstprogramm profilieren, das als in Bash integrierte Shell verfügbar ist – aber auch als eigenständiges ausführbares Programm. Das Ausführen der beiden Beispielbefehle zeigt beispielsweise, dass das erste Beispiel 0,012 Sekunden länger dauerte als das zweite.

$ time echo "foo\nbar\nbaz" | sed 1q | awk '{ print $0 " cats" }'
foo\nbar\nbaz cats

real    0m0.056s
user    0m0.000s
sys     0m0.045s

$ time echo "foo\nbar\nbaz" | awk 'NR == 1 { print $0 " cats" }'
foo\nbar\nbaz cats

real    0m0.044s
user    0m0.000s
sys     0m0.031s

Beachten Sie, dass Profilierungs-Benchmarks von der Systemlast und anderen einschränkenden Faktoren beeinflusst werden. Sie müssen dies also viele Male wiederholen, um ein echtes Bild davon zu erhalten, welche Version schneller als die andere ist.


* Mit MS Windows, ForkingIstteurer, daher macht es einen Unterschied, wenn man in Umgebungen wie Cygwin die Anzahl der gestarteten Prozesse minimiert.

Antwort2

Es reicht aus,awk(odersed) Werkzeug für solche einfachen Fälle. Eine Kombination mehrerer Werkzeuge wäre zu kompliziert und oft redundant:

echo -e "foo\nbar\nbaz" | awk 'NR==1{print $0" cats"}'

Die Ausgabe:

foo cats

Welche Faktoren sollte ich berücksichtigen?

Stellen Sie sicher, dass die erforderliche Textverarbeitung die Kombination mehrerer verschiedener Tools erfordert. Andernfalls nutzen Sie die Leistung eines einzelnen Tools.

Nehmen wir an, ich muss nur ein bestimmtes Wort vor dem ersten Wort in der Eingabezeichenfolge hinzufügen - das geht auch ganz einfach mitsedWerkzeug:

echo -e "foo\nbar\nbaz" | sed 's/^.*$/& cats/; 1q'
foo cats

echo -e, eFlag „ermöglicht die Interpretation von Backslash-Escapezeichen“


Wie dem auch sei, es hängt davon ab, wie komplex Ihr Eingabetext ist und wie ausgefeilt Ihre Textverarbeitungsregeln sind.

verwandte Informationen