GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Drucken Sie Linien zwischen Start- und Endmuster, aber wenn kein Endmuster vorhanden ist, drucken Sie nicht

Sie können dies wie folgt erreichen:

$ sed -e '
    /BEGIN/,/END/!d
    H;/BEGIN/h;/END/!d;g
' inp

Wie es funktioniert, speichert es den Anfangs-/Endbereich von Zeilen im Haltebereich. Dann löscht, bis Sie die END-Zeile treffen. An diesem Punkt erinnern wir uns an das, was in der Warteschleife ist. OTW, wir bekommen nichts raus.HTH.


cat input |
sed '/\*\*\*\*\* BEGIN \*\*\*\*\*/,/\*\*\*\*\* END *\*\*\*\*/ p;d' | 
tac |
sed '/\*\*\*\*\* END \*\*\*\*\*/,/\*\*\*\*\* BEGIN *\*\*\*\*/ p;d' |
tac

Es funktioniert mit tac Kehren Sie die Zeilen um, sodass sed kann beide Trennzeichen in beiden Reihenfolgen finden.


Mit pcregrep :

pcregrep -M '(?s)BEGIN.*?END'

Das funktioniert auch, wenn BEGIN und END in derselben Zeile stehen, aber nicht in Fällen wie:

BEGIN 1 END foo BEGIN 2
END

Wobei pcregrep fängt die erste BEGIN 1 END ab , aber nicht die zweite.

Um diese zu handhaben, mit awk , könnten Sie Folgendes tun:

awk '
  !inside {
    if (match($0, /^.*BEGIN/)) {
      inside = 1
      remembered = substr($0, 1, RLENGTH)
      $0 = substr($0, RLENGTH + 1)
    } else next
  }
  {
    if (match($0, /^.*END/)) {
      print remembered $0
      if (substr($0, RLENGTH+1) ~ /BEGIN/)
        remembered = ""
      else
        inside = 0
    } else
      remembered = remembered $0 ORS
  }'

Bei einer Eingabe wie:

a
BEGIN blah END BEGIN 1
2
END
b
BEGIN foo END
c
BEGIN
bar
END BEGIN
baz END
d
BEGIN
xxx

Es ergibt:

BEGIN blah END BEGIN 1
2
END
BEGIN foo END
BEGIN
bar
END BEGIN
baz END

Beide müssen alles vom BEGIN bis zum folgenden END im Speicher speichern. Wenn Sie also eine riesige Datei haben, deren erste Zeile BEGIN enthält, aber kein END, wird die ganze Datei umsonst im Speicher abgelegt.

Der einzige Weg, dies zu umgehen, wäre, die Datei zweimal zu verarbeiten, aber das geht natürlich nur, wenn die Eingabe eine normale Datei ist (nicht zum Beispiel eine Pipe).


Linux
  1. Warum funktioniert Tomcat mit Port 8080, aber nicht mit 80?

  2. der android emulator startet nicht, avd

  3. Linux free zeigt eine hohe Speicherauslastung, top jedoch nicht

  4. wc -l zählt NICHT zuletzt in der Datei, wenn es kein Zeilenendezeichen hat

  5. docker images zeigt Bild, docker rmi sagt kein solches Bild oder Referenz existiert nicht

Warum funktioniert der reguläre Ausdruck in X, aber nicht in Y?

Linien zwischen (und ausschließenden) zwei Mustern drucken?

Zeilen zwischen (und einschließlich) zwei Mustern drucken?

Wie Grep-Zeilen, die nicht mit „#“ oder „;“ beginnen?

Linux – Warum funktioniert Locale Es_mx, aber nicht Es?

Linux – /sbin/init existiert nicht?