Unten ist der Text in der Datei:
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
Ich muss nach "42B" suchen und die Ausgabe aus dem obigen Text wie folgt erhalten:
Pseudo name=Apple
Code=42B
state=fault
Hat jemand eine Idee, wie dies mit grep
/ awk
/ erreicht werden kann sed
?
Antworten:
Mit
awk
RS=
Ändert das Trennzeichen für Eingabedatensätze von einer Zeilenvorschubzeile in Leerzeilen. Wenn ein Feld in einem Datensatz enthält,/42B/
drucken Sie den Datensatz.''
(die Nullzeichenfolge) ist ein magischer Wert, der verwendet wird, um Leerzeilen gemäß POSIX darzustellen :Die Ausgabe-Absätze werden nicht getrennt, da das Ausgabe-Trennzeichen eine einzelne neue Zeile bleibt. Stellen Sie das Trennzeichen für Ausgabedatensätze auf zwei neue Zeilen ein, um sicherzustellen, dass zwischen den Ausgabeabschnitten eine leere Zeile steht:
quelle
FILENAME
), ist es keine schlechte Idee, die Umleitung zu verwenden, da dies Probleme mit Dateinamen vermeidet, die enthalten=
oder mit-
(oder sein-
) beginnen, für konsistente Fehlermeldungen sorgt und das Ausführenawk
oder Ausführen vermeidet andere Umleitungen, wenn die Eingabedatei nicht geöffnet werden kann.Angenommen, die Daten sind so strukturiert, dass es immer die Zeile davor und danach ist. Dann können Sie die Schalter grep
-A
(after) und-B
(before) verwenden, um anzugeben, dass die Zeile 1 vor dem Match und die Zeile 1 danach enthalten soll:Wenn Sie vor und nach dem Suchbegriff die gleichen Zahlenzeilen haben möchten, können Sie den
-C
(Kontext-) Schalter verwenden:Wenn Sie beim Abgleichen mehrerer Zeilen strenger vorgehen möchten, können Sie das Tool verwenden
pcregrep
, um ein Muster über mehrere Zeilen hinweg abzugleichen:Das obige Muster stimmt wie folgt überein:
-M
- mehrere Zeilen'Pseudo.*\n.*42B.*\nstate.*'
- Stimmt mit einer Gruppe von Zeichenfolgen überein, bei der die erste Zeichenfolge mit dem Wort beginnt,"Pseudo"
gefolgt von beliebigen Zeichen bis zum Zeilenende\n
, gefolgt von beliebigen Zeichen bis zur Zeichenfolge,"42B"
gefolgt von beliebigen Zeichen bis zum anderen Zeilenende (\n
), gefolgt von der Zeichenfolge"state"
gefolgt von beliebigen Zeichen.quelle
-C
(context) kann als Verknüpfung verwendet werden, wenn-A
und gleich-B
sind.Es gibt wahrscheinlich einen ähnlich einfachen Weg, dies mit awk zu tun, aber in Perl:
Das bedeutet im Grunde, dass Sie die Datei in durch Leerzeilen begrenzte Abschnitte aufteilen und dann nur die Abschnitte drucken müssen, die Ihrem regulären Ausdruck entsprechen.
quelle
cat
;perl -00 -ne 'print if /42B/' file
Die
grep
von einigen Unix-Varianten haben die-p
Kennzeichnung für "Absatz". Ich weiß, dass AIX es tut .würde genau das tun, wonach du fragst. YMMV und GNU grep haben dieses Flag nicht.
quelle
Eine andere Perl-Lösung ohne nachgestellte Leerzeile:
Beispiel
quelle
perl -00 -ne 'print if /42B/' file
.