BEARBEITET: Nach der brillanten Antwort von @john1024 würde ich gerne wissen, ob es möglich ist:

BEARBEITET: Nach der brillanten Antwort von @john1024 würde ich gerne wissen, ob es möglich ist:

Ich habe eine Datei prova.txtwie diese:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

extra1
extra2
bla

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

extra2
bla
bla

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

und ich muss von "Start to grab here" bis zur ersten leeren Zeile greppen. Die Ausgabe sollte so aussehen:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

Wie Sie sehen, sind die Zeilen nach „Start to grab here“ zufällig, daher funktioniert das Grep-Flag -A -B nicht:

cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt

Können Sie mir helfen, eine Methode zu finden, die die erste Zeile erfasst (als „Start to grab from here“), bis eine leere Zeile erscheint? Ich kann nicht vorhersagen, wie viele zufällige Zeilen ich nach „Start to grab from here“ haben werde.

Jede Unix-kompatible Lösung ist willkommen (grep, sed, awk ist besser als Perl oder ähnliches).

BEARBEITET: Nach der brillanten Antwort von @john1024 würde ich gerne wissen, ob es möglich ist:

1. Den Block sortieren (nach Start zum Greifen von hier: 1, dann 1, dann 2)

2° entfernen Sie 4 (alphabetisch zufällige) Zeilen fix1,fix2,fix3,fix4, aber es sind immer 4

3° Entfernen Sie ggf. zufällige Duplikate, wie beim Befehl sort -u

Die endgültige Ausgabe sollte wie folgt aussehen:

# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4

#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

oder

# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

Die zweite Ausgabe ist besser als die erste. Es ist ein anderer Unix-Befehlstrick erforderlich.

Antwort1

Verwenden von awk

Versuchen:

$ awk '/Start to grab/,/^$/' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

/Start to grab/,/^$/definiert einen Bereich. Er beginnt mit einer beliebigen übereinstimmenden Zeile Start to grabund endet mit der ersten ^$folgenden leeren Zeile.

Verwenden von sed

Mit sehr ähnlicher Logik:

$ sed -n '/Start to grab/,/^$/p' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

-nweist sed an, nichts auszudrucken, sofern wir es nicht ausdrücklich dazu auffordern. /Start to grab/,/^$/pweist ihn an, alle Zeilen in dem durch definierten Bereich auszudrucken /Start to grab/,/^$/.

Antwort2

Ich poste eine alternative Lösung, da sie für manche Anwendungsfälle nützlich sein könnte. Diese Lösung entspricht nicht genau den angegebenen Anforderungen. Die beste Lösung finden Sie in der Antwort von @John1024.

Sie können awk verwenden, wobei der Datensatztrenner auf eine leere Zeichenfolge eingestellt ist. awk interpretiert diese als leere Zeilenumbrüche:

$ awk '/Start/' RS= prova.txt 
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

Diese Version behält die leeren Zeilenumbrüche in der Ausgabe nicht bei. Sie zeigt auch den Kontext vor der Übereinstimmung an, falls vorhanden. Dieses Verhalten kann sehr nützlich sein, wenn Sie in einer Datei nach etwas suchen und den durch Zeilenumbrüche getrennten Block sehen möchten, zu dem es gehört, zum Beispiel:

$ awk '/random1546/' RS= prova.txt 
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

Ich finde dies beispielsweise beim Suchen nach Dingen in iniDateien nützlich.

verwandte Informationen