Wie wählt man Linien zwischen zwei Mustern?
Habe ich eine Datei wie die folgende, und ich möchte drucken Sie die Linien zwischen zwei gegebenen Muster PAT1
und PAT2
.
1
2
PAT1
3 - first block
4
PAT2
5
6
PAT1
7 - second block
PAT2
8
9
PAT1
10 - third block
Habe ich gelesen, So wählen Sie Linien zwischen zwei marker-Muster, die auftreten können, mehrere Male mit awk/sed aber ich bin neugierig zu sehen, alle möglichen Kombinationen von diesen, entweder drucken Sie das Muster oder nicht.
Wie kann ich die Linien zwischen zwei mustern?
InformationsquelleAutor der Frage fedorqui | 2016-08-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Drucken Linien zwischen PAT1 und PAT2
Oder mit Variablen:
Wie funktioniert das?
/PAT1/
entspricht, Zeilen mit diesem text, sowie/PAT2/
tut./PAT1/{flag=1}
legt dieflag
wenn der textPAT1
ist gefunden, in einer Zeile./PAT2/{flag=0}
entfernt denflag
wenn der textPAT2
ist gefunden, in einer Zeile.flag
ist ein Muster mit dem Standard-Aktion, dieprint $0
: wennflag
ist gleich 1 die Zeile wird gedruckt. Auf diese Weise, es wird gedruckt, alle jene Linien, die aus der ZeitPAT1
Auftritt und bis zu den nächstenPAT2
zu sehen ist. Dies wird auch drucken die Zeilen aus dem letzten SpielPAT1
bis zum Ende der Datei.Drucken Linien zwischen PAT1 und PAT2 - nicht einschließlich PAT1 und PAT2
Diese verwendet
next
überspringen Sie die Zeile, die enthältPAT1
um dies zu vermeiden, wird gedruckt.Dieser Aufruf
next
gelöscht werden können, durch Neuanordnung der Blöcke:awk '/PAT2/{flag=0} flag; /PAT1/{flag=1}' file
.Drucken Linien zwischen PAT1 und PAT2 - einschließlich PAT1
Indem
flag
ganz am Ende, es löst die Aktion aus, die eingestellt wurde, entweder PAT1 oder PAT2: zum drucken auf PAT1, nicht das Bedrucken von PAT2.Drucken Linien zwischen PAT1 und PAT2 - einschließlich PAT2
Indem
flag
ganz am Anfang, es löst die Aktion wurde zuvor festgelegt haben und daher drucken die Schließung Muster, aber nicht der Ausgangspunkt ein.Drucken Linien zwischen PAT1 und PAT2 - ohne die Zeilen aus der letzten PAT1 an das Ende der Datei, wenn keine andere PAT2 tritt
Diese basiert auf eine Lösung von Ed Morton.
Als ein one-liner:
Dieser hält alle ausgewählten Zeilen in einen Puffer, der wird bevölkert von dem moment an PAT1 gefunden wird. Dann, er bleibt gefüllt, mit den folgenden Zeilen, bis PAT2 gefunden wird. In diesem Punkt, es druckt die gespeicherten Inhalte und leert den Puffer.
InformationsquelleAutor der Antwort
Was über die klassische
sed
Lösung?Drucken Linien zwischen PAT1 und PAT2
oder sogar (Dank Sundeep):
Den oben schließt den Grenzen des Bereichs.
Drucken Linien zwischen PAT1 und PAT2 - einschließlich PAT1 und PAT2
Folgende umfassen würde, die den Grenzen des Bereichs, die ist sogar noch einfacher:
Drucken Linien zwischen PAT1 und PAT2 - einschließlich PAT1
Folgendes umfasst nur den Bereich start:
Drucken Linien zwischen PAT1 und PAT2 - einschließlich PAT2
Folgendes umfasst nur den Bereich Ende:
InformationsquelleAutor der Antwort hek2mgl
Mit
grep
mit PCRE (wo verfügbar) print-Marken und Linien zwischen den Markierungen:-P
perl-regexp, PCRE. Nicht in allengrep
Varianten-z
Behandlung der Eingabe als einen Satz von Zeilen, jedeterminiert mit einem null-byte (statt einem Zeilenumbruch
-o
drucken Sie immer nur passende,(?s)
DotAll, dh. dot findet Zeilenumbrüche sowie(.*?)
nongreedy finden\Z
Match nur am Ende der Zeichenfolge oder vor dem newline am EndeDrucken von Linien zwischen den Markierungen ohne Ende-marker:
(.*?)(?=(\nPAT2|\Z))
nongreedy finden mit lookahead für\nPAT2
und\Z
Print-Linien zwischen dem Marker ohne Marker:
(?<=PAT1\n)
positive lookbehind fürPAT1\n
Drucken von Linien zwischen den Markierungen ohne start-marker:
InformationsquelleAutor der Antwort James Brown
Hier ist ein weiterer Ansatz,
Umfassen sowohl Muster (Standard -)
Maske beide Muster
Maske beginnen Muster
Maske Ende-Muster
InformationsquelleAutor der Antwort karakfa
Können Sie tun, was Sie wollen mit
sed
durch Unterdrückung der normalen Druck-Muster-Raum mit-n
. Zum Beispiel, um gehören das Muster in dem Ergebnis, das Sie tun können:Zu ausschließen die Muster und nur das drucken, was zwischen Ihnen:
Denen bricht als
sed -n '/PAT1/,/PAT2/
- suchen Sie den Bereich zwischenPAT1
undPAT2
und Druck unterdrücken;/PAT1/{n};
- wenn es passtPAT1
bewegen zun
(nächsten) Zeile;/PAT2/{d};
- wenn es passtPAT2
Zeile löschen;p
- drucken Sie alle Zeilen, fielen in/PAT1/,/PAT2/
und wurden nicht übersprungen oder gelöscht werden.InformationsquelleAutor der Antwort David C. Rankin
Alternativ:
Dieser löscht alle Zeilen außer für diejenigen, die zwischen und einschließlich BEGINN und ENDE, dann die
//d
löscht den START-und END-Zeilen, da//
Ursachen sed zur Verwendung der bisherigen Muster.InformationsquelleAutor der Antwort Daedelus