Ich habe eine Datei wie unten.
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
~PAR2~
This is Par2 line 1
This is Par2 line 2
Par Finished
Wenn ich übergebe , sollte ich alle Zeilen zwischen und Zeile PAR1
erhalten . Wie kann ich das erreichen? Ich habe nach und gesucht und konnte keine Optionen finden.PAR1
Par Finished
awk
sed
Antwort1
Wenn Sie die Kopf- und Fußzeile möchten, dann ist es ziemlich einfach mit sed
zB
sed -n "/^~PAR1~$/,/Par Finished/p"
Dies ist einfach mit einer Variablen zu verwenden
START=PAR1
sed -n "/^~$START~$/,/Par Finished/p"
Wir können die letzte Zeile auch zu einer Variablen machen
START=PAR1
END="Par Finished"
sed -n "/^~$START~$/,/$END/p"
Das Ergebnis sieht wie folgt aus:
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Wenn Sie weder Start-/Endzeilen noch Leerzeilen möchten, ist die Sache etwas komplizierter.
Es gibt vielleicht bessere Möglichkeiten, aber das hier funktioniert bei mir:
sed -n "/^~$START~$/,/$END/ { /^~$START~$/d ; /$END/d ; /^$/d ; p }"
Das Ergebnis davon ist
This is Par1 line 1
This is Par1 line 2
Antwort2
Par Finished
Sie können die Zeile (mit optionalen nachfolgenden Leerzeilen) als Datensatztrennzeichen verwenden (und sie dann ersetzen, um den Datensatz zu vervollständigen).
awk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {print $0,"\nPar Finished"}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Wenn Sie über GNU
awk verfügen, können Sie den Datensatztrenner mit der speziellen Variable wiederherstellen RT
(und dabei die zusätzlichen Zeilenumbrüche entfernen, wenn Sie möchten).
gawk -vRS='\nPar Finished\n*' -vp='PAR1' '$0 ~ p {sub("\n*$", "", RT); print $0,RT}' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Natürlich, wenn Sie nicht passieren müssen eineVariable Par1
Sie verwenden einen einfachen Regex-Bereich
awk '/PAR1/,/Par Finished/' parfile
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
Antwort3
Mit grep
und pcre
für ausreichend kleine Dateieingaben
$ s="PAR1"
$ grep -oPz "(?s)[^\n]*${s}.*?\n.*?Par Finished.*?\n" ip.txt
~PAR1~
This is Par1 line 1
This is Par1 line 2
Par Finished
So erhalten Sie Linien zwischen den Mustern:
$ grep -oPz "(?s)${s}.*?\n\K.*?(?=Par beendet)" ip.txt Dies ist Par1 Zeile 1 Dies ist Par1 Zeile 2
Variable ändern inPAR2
$ s="PAR2" $ grep -oPz "(?s)${s}.*?\n\K.*?(?=Par beendet)" ip.txt Dies ist Par2 Linie 1 Dies ist Par2 Linie 2
Referenz: Regex (grep) für mehrzeilige Suche