Was sind die genauen Unterschiede zwischen awk und grep? [geschlossen]

30

Wir wissen, dass wir die zweite Spalte der gewünschten Zeile mithilfe dieser beiden Techniken aus einer Datei abrufen können:

awk '/WORD/ { print $2 }' filename

oder

grep WORD filename| cut -f 2 -d ' '

Meine Fragen sind:

  • Was sind die Unterschiede zwischen den beiden obigen Befehlen?
  • Welches hat die beste Leistung?
  • Was sind die Vorteile der Verwendung awkgegenüber der Verwendung cutund umgekehrt?
  • Welche Möglichkeiten haben awkwir cutund umgekehrt?
Networker
quelle
ist das echo filenameoder cat filename?
Avinash Raj
@AvinashRaj sorry bearbeitet
Networker

Antworten:

35

Der auffälligste Unterschied zwischen Ihren beiden Zeilen hängt von der Eingabe ab. cutnimmt ein einzelnes Zeichen -dals Feldbegrenzer (der Standardwert ist TAB) und jedes einzelne Vorkommen dieses Zeichens startet ein neues Feld. awkist jedoch flexibler. Das Trennzeichen befindet sich in der FSVariablen und kann eine leere Zeichenfolge (jedes Eingabezeichen bildet ein separates Feld), ein einzelnes Zeichen oder ein regulärer Ausdruck sein. Der Sonderfall eines einzelnen Leerzeichens (Standard) bedeutet, dass eine beliebige Folge von Leerzeichen geteilt wird. Auch awkführende Unterdrückt Leerzeichen standardmäßig.

Bitte vergleichen Sie:

$ echo "abc def" | cut -f 2 -d ' '
def
$ echo "abc    def" | cut -f 2 -d ' '

$ echo " abc def" | cut -f 2 -d ' '
abc


$ echo "abc def" | awk '{ print $2 }'
def
$ echo "abc    def" | awk '{ print $2 }'
def
$ echo " abc def" | awk '{ print $2 }'
def

Hier awkteilt sich auf die Reihenfolge der Räume zwischen abcund defwährend cutnimmt jeden Raum als Separator.

Was Sie einnehmen, hängt davon ab, was Sie erreichen möchten. Ansonsten würde ich erwarten cut, schneller zu sein, da es sich um ein kleineres Einzweckwerkzeug handelt, awkdas eine eigene Programmiersprache hat.

Dubu
quelle
das, was ich als Antwort möchte, danke ich werde die Frage als beantwortet markieren @ Dubu
Networker
1
cutist wahrscheinlich schneller als Awk alleine , aber es ist nicht so sicher, dass grep ... | cutes schneller als reines Awk sein wird.
Wildcard
8

Im Allgemeinen ist ein Werkzeug umso schneller, je spezialisierter es ist. So in den meisten Fällen, können Sie erwarten , cutund grepschneller als sedund sedals schneller zu sein awk. Wenn Sie längere Pipelines von einfacheren Werkzeugen mit einem einzigen Aufruf eines komplexeren Werkzeugs vergleichen, gibt es keine Faustregel. Dies ist nur bei großen Eingaben (z. B. Millionen von Zeilen) von Bedeutung. Bei kurzen Eingaben sehen Sie keinen Unterschied.

Der Vorteil komplexerer Tools ist natürlich, dass sie mehr können.

Ihre Befehle verwenden unnötigerweise cat. Verwenden Sie stattdessen die Umleitung (insbesondere, wenn Sie sich Gedanken über die Geschwindigkeit machen, obwohl Sie sich wahrscheinlich keine Gedanken über die Geschwindigkeit machen sollten, bis Sie Benchmarks1 ausgeführt haben).

<fileName awk '/WORD/ { print $2 }'
<fileName grep WORD | cut -f 2 -d ' '

Diese Befehle sind fast gleichwertig. Die Unterschiede sind:

  • awk und grep haben unterschiedliche Regexp-Syntaxen . Awk und grep -Ehaben fast identische Regexp-Syntax (erweiterte reguläre Ausdrücke).
  • cut -d ' 'behandelt jedes einzelne Leerzeichen als Begrenzer. Das Standardtrennzeichen von Awk ist eine beliebige Whitespace-Sequenz, die aus mehreren Leerzeichen, einem Tabulator usw. bestehen kann. Sie können keine willkürlichen Whitespace-Sequenzen als Trennzeichen verwenden cut. Um einzelne Leerzeichen als Trennzeichen in awk zu verwenden, stellen Sie das Feldtrennzeichen auf einen regulären Ausdruck ein, der einem einzelnen Leerzeichen entspricht, mit Ausnahme eines regulären Ausdrucks, der aus einem einzelnen Leerzeichen besteht awk -F '[ ]' '/WORD/ {print $2}'.

¹ Die erste Regel zur Programmoptimierung: Tun Sie es nicht. Die zweite Regel der Programmoptimierung (nur für Experten!): Tun Sie es noch nicht. - Michael A. Jackson

Gilles 'SO - hör auf böse zu sein'
quelle
1

Ihr Befehl,

cat fileName | awk '/WORD/ { print $2 }'

Sie brauchen nicht einmal einen catBefehl. Sie können versuchen,

awk '/WORD/ { print $2 }' filename

Und der folgende Befehl leitet die Ausgabe von cat zu grep und dann zu cut um,

cat fileName | grep WORD | cut -f 2 -d ' '

Höchstwahrscheinlich müssen wir die Ausgabeumleitung vermeiden. Awk erledigt die Aufgabe in einer Zeile, cutbenötigt jedoch einen grepBefehl, um nur die Zeilen abzurufen, die ein bestimmtes Wort enthalten, und druckt die Spalte 2 entsprechend dem Trennzeichen.

Sie können die Dinge in awk tun, wenn cut nicht funktioniert.

Avinash Raj
quelle
3
ps du brauchst auch keinen cat befehl für grep. Sie können es einfach tun grep WORD filename.
Fotos
@ edvinas.me yep.
Avinash Raj