2016-05-03 15 views
0

ich eine Datei vom Format haben:Erhalten Linien zwischen pattern1 OR erhalten Linien, die pattern2 entsprechen - sed/awk

PATTERN2 
PATTERN1 
text I want 
more text I want ... 
PATTERN1 
text don't want 
text don't want 
text don't want 
PATTERN2 
PATTERN1 
text I want 
more text I want ... 
PATTERN1 
text don't want 
text don't want 
text don't want 
... 

ich den Text zwischen Vorkommen von MUSTER1 bekommen können mit sed.

sed -n -e '/PATTERN1/,/PATTERN1/ p' my_file.txt 

Ich kann auch Linien mit PATTERN2 übereinstimmen.

sed -n -e '/PATTERN2/ p' my_file.txt 

Allerdings habe ich Schwierigkeiten, Zeilen, die eines dieser Muster entsprechen. Was ich als Ausgabe möchte, ist

PATTERN2 
PATTERN1 
text I want 
more text I want ... 
PATTERN1 
PATTERN2 
PATTERN1 
text I want 
more text I want ... 
PATTERN1 

Danke für Ihre Hilfe.

Antwort

1

Sie können einfach die beiden -e Befehle zusammenfügen. Es wird sie sowohl für jede Zeile

sed -n -e '/PATTERN1/,/PATTERN1/ p' -e '/PATTERN2/ p' my_file.txt 

Vorsicht ausgeführt werden: wenn /PATTERN2/ Matches innerhalb /PATTERN1/, wird diese Linie zweimal gedruckt werden

Es gibt auch eine komplizierte sed Befehl, der die oben Vorsicht löst:

sed -e '/PATTERN1/,/PATTERN1/ !{ 
    /PATTERN2/ !d 
}' 

Zwischen den Markierungen nicht ausführen alles löschen außer PATTERN2. Mit anderen Worten, löschen Sie außerhalb der Marker alles außer PATTERN2.

0

können Sie diesen awk Befehl verwenden:

awk '/PATTERN1/{p=!p} p || /PATTERN1|PATTERN2/' file 

PATTERN2 
PATTERN1 
text I want 
more text I want ... 
PATTERN1 
PATTERN2 
PATTERN1 
text I want 
more text I want ... 
PATTERN1 
0

Für Wartbarkeit, testen Sie nie den gleichen Wert hart codiert (zB PATTERN1) mehrfach:

$ awk '/PATTERN1/{if (f) print; f=!f} f || /PATTERN2/' file 
PATTERN2 
PATTERN1 
text I want 
more text I want ... 
PATTERN1 
PATTERN2 
PATTERN1 
text I want 
more text I want ... 
PATTERN1 

Wenn Sie PATTERN1 ersetzen möchten mit FOO in Zukunft dann mit dem obigen Code müssen Sie nur diese Änderung an einem Ort vornehmen.

0

Eine leicht lesbare sed Version:

sed -n "/PATTERN2/p;/PATTERN1/,/PATTERN1/p" 

Ich hoffe, das hilft.

  • -n drucke nicht standardmäßig
  • /PATTERN2/Singular Matchstring
  • p drucken es
  • /MUSTER1/erste Matchstring
  • , alles zwischen
  • /MUSTER1/zweite Übereinstimmungszeichenfolge
  • p es drucken