Ich versuche, in etwas zu leiten, das nur den ersten „Absatz“ oder „Abschnitt“ zurückgibt, getrennt durch eine Leerzeile. Ich dachte, ich könnte awk
oder verwenden sed
, um einen Bereich wie in einigen anderen Antworten zu erhalten, aber es scheint nicht zu funktionieren.
$ cat txt
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.4-0ubuntu1
Supported: 3y
$ cat txt |awk '/^Package:/,/^$/'
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.4-0ubuntu1
Supported: 3y
Sollte nicht nur der erste „Abschnitt“ zurückgegeben werden? (gemäß: Grep ausgehend von einem festen Text, bis zur ersten leeren Zeile Und https://www.unix.com/shell-programming-and-scripting/148692-awk-script-match-pattern-till-blank-line.html)
- Wenn ich es verwende,
grep -ve ^$
werden die Leerzeilen entfernt, so dass keine Sonderzeichen vorhanden sind. Wenn ich versuche, einen anderen Teil zu extrahieren, erhalte ich die Teile aus beiden „Abschnitten“:
$ cat txt |awk '/^Package:/,/^Version:/' Package: plasma-desktop Architecture: amd64 Version: 4:5.12.9.1-0ubuntu0.1 Package: plasma-desktop Architecture: amd64 Version: 4:5.12.4-0ubuntu1
Wenn ich
sed -n '/^Package:/,/^$/p'
oder verwendesed -n '/^Package:/,/^Version:/p'
, erhalte ich die gleichen Ergebnisse wie mit dem entsprechenden awk.
Wie kann ich das Problem beheben awk
bzw. sed
nach dem ersten Auftreten stoppen?
Antwort1
Genau aus diesem Grund verfügt awk über einen Absatzmodus:
$ awk -v RS= 'NR==1' file
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y
und das Drucken des zweiten Datensatzes ist nur die offensichtliche Änderung von NR==1
in NR==2
:
$ awk -v RS= 'NR==2' file
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.4-0ubuntu1
Supported: 3y
Verwenden Sie übrigens niemals Bereichsausdrücke – sie machen den Code für triviale Probleme etwas kürzer als die Verwendung einer Flagge, aber wenn sich Ihre Anforderungen auch nur im Geringsten ändern, müssen Sie ihn komplett neu schreiben oder die Bedingungen duplizieren. Wenn Sie also denken, dass Sie /begin/,/end/
sed oder awk verwenden möchten, verwenden Sie /begin/{f=1} f{print} /end/{f=0}
stattdessen awk, und das gibt Ihnen VIEL mehr Kontrolle darüber, wann/wie die Anfangs-/Endzeilen usw. gedruckt werden.
Antwort2
In /begin/,/end/
werden die „Aktionsflags“ bei jedem /begin/
gefundenen Treffer aktiviert und bei gefundenem Treffer deaktiviert /end/
. Die Begrenzungslinien mit „Beginn“ und „Ende“ werden ebenfalls gedruckt.
Ihre Eingaben haben folgende Auswirkungen (in den folgenden Beispielen ist hinter den gedruckten Zeilen ein Kommentar angebracht):
- Mit
'/^Package:/,/^$/'
:
Package: plasma-desktop #TURN ON
Architecture: amd64 #
Version: 4:5.12.9.1-0ubuntu0.1 #
Supported: 3y #
#TURN OFF
Package: plasma-desktop #TURN ON
Architecture: amd64 #
Version: 4:5.12.4-0ubuntu1 #
Supported: 3y #
- Mit
'/^Package:/,/^Version:/'
:
Package: plasma-desktop #TURN ON
Architecture: amd64 #
Version: 4:5.12.9.1-0ubuntu0.1 #TURN OFF
Supported: 3y
Package: plasma-desktop #TURN ON
Architecture: amd64 #
Version: 4:5.12.4-0ubuntu1 #TURN OFF
Supported: 3y
Um nur den Absatz ab "Paket:" zu drucken, können Sie schreiben
sed -ne '/^$/q' -e '/^Package:/,$p' file
sed
bricht die Verarbeitung der Datei ab, sobald es eine leere Zeile findet, weil /^$/q
.
Mit awk
:
awk '/^$/{exit};/^Package:/,0' file
Antwort3
Kommentar vonQuasimodo
/begin/,/end/
ruft Zeilen ab, die diesen regulären Ausdrücken entsprechen, einschließlich der Begrenzungslinien. begin schaltet den Druck ein und end schaltet ihn aus. Die Zeile direkt nach Ihrer Leerzeile schaltet den Druck wieder ein, weil sie auch enthältPackage:
.
Mir ist aufgefallen, dass ich „to“ verwenden sed
und ändern kann und es dann am Anfang beginnt. Da es nur einen Anfang gibt, wird es nur einmal übereinstimmen./begin/
0
$ cat txt |sed -n '0,/^$/p'
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y