ich benutze das
cat foo.txt | sed '/bar/d'
um Zeilen zu entfernen, die den String bar
in der Datei enthalten.
Ich möchte jedoch diese Zeilen und die Zeile direkt danach entfernen . Vorzugsweise in sed
, awk
oder einem anderen Werkzeug , das in MinGW32 vorhanden ist.
Es ist eine Art Gegenteil das , was ich in kann grep
mit -A
und -B
Linien sowie Linien zu drucken , passend vor / nach der angepassten Linie.
Gibt es einen einfachen Weg, dies zu erreichen?
text-processing
sed
awk
replace
jakub.g
quelle
quelle
Antworten:
Wenn Sie GNU sed haben (also nicht eingebettetes Linux oder Cygwin):
Wenn Sie
bar
zwei aufeinanderfolgende Zeilen haben, wird die zweite Zeile gelöscht, ohne sie zu analysieren. Zum Beispiel, wenn Sie eine 3-Zeilen - Dateibar
/bar
/foo
, diefoo
wird Linie bleiben.quelle
bar
s, daher ist dieses super einfach zu merken.sed '/bar/d'
wenn Sie nur die Zeile mit einer bestimmten Zeichenfolge entfernen möchten und nicht die nächste.sed '/math/q'
sed '/bar/d'
Wenn
bar
dies in aufeinanderfolgenden Zeilen vorkommen kann, können Sie Folgendes tun:Dies kann angepasst werden, um mehr als 2 Zeilen zu löschen, indem die 2 oben durch die Anzahl der zu löschenden Zeilen einschließlich der übereinstimmenden geändert wird.
Wenn nicht, ist dies
sed
mit der Lösung von @MichaelRollins einfach zu erledigen oder:quelle
/bar/
mit/bar|baz|whatever/
. Insed
dieser Syntax scheint nicht zu funktionieren.sed
nach "erweiterten" regulären Ausdrücken fragen . Weitere Informationen finden Sie hier: gnu.org/software/sed/manual/html_node/… . Bitte beachten Sie, dass dies auch für giltgrep
. Hier ist mein eigenes Arbeitsbeispiel:echo $'0a\n1b\n2c' | sed '/0a\|1b/d'
.Ich spreche nicht fließend sed, aber es ist einfach, dies in awk zu tun:
Das awk-Skript lautet: Für eine Zeile, die einen Balken enthält, holen Sie sich die nächste Zeile (getline) und überspringen Sie dann die gesamte nachfolgende Verarbeitung (next). Das 1-Muster am Ende druckt die restlichen Zeilen.
Aktualisieren
Wie in dem Kommentar ausgeführt, funktionierte die obige Lösung nicht aufeinanderfolgend
bar
. Hier ist eine überarbeitete Lösung, die dies berücksichtigt:Wir lesen jetzt weiter, um alle / Balken / Zeilen zu überspringen.
quelle
grep -A
100% zu replizieren , müssen Sie auch eine beliebige Anzahl aufeinanderfolgenderbar
Zeilen korrekt behandeln (indem Sie den gesamten Block und eine Zeile danach entfernen).Sie werden die Skriptfunktionen von sed nutzen wollen, um dies zu erreichen.
Beispieldaten:
Mit dem Befehl "N" wird die nächste Eingabezeile in den Musterraum eingefügt. In Kombination mit der Zeile aus der Musterübereinstimmung (/ bar /) werden die Zeilen angezeigt, die Sie löschen möchten. Sie können dann normal mit dem Befehl "d" löschen.
quelle
sed -e '/bar/{N;d}' sample1.txt
Wenn eine Zeile, die unmittelbar auf eine Übereinstimmung folgt, entfernt werden soll, muss Ihr
sed
Programm aufeinanderfolgende Übereinstimmungen berücksichtigen. Mit anderen Worten, wenn Sie eine Zeile nach einer Übereinstimmung entfernen, die auch übereinstimmt, sollten Sie wahrscheinlich auch die darauf folgende Zeile entfernen.Es ist einfach genug implementiert - aber man muss ein wenig nachschauen.
Dabei werden Halte- und Musterbereiche für jede eingelesene Zeile vertauscht, sodass die letzte Zeile jedes Mal mit der aktuellen verglichen werden kann. Wenn also
sed
eine Zeile gelesen wird, tauscht sie den Inhalt ihrer Puffer aus - und die vorherige Zeile ist dann der Inhalt ihres Editierpuffers, während die aktuelle Zeile in den Hold-Space gestellt wird.So
sed
prüft die vorhergehende Zeile für ein Spiel zumatch
, und wenn sie!
nicht die beiden Ausdrücke in der gefundene{
Funktion}
ausgeführt werden .sed
wirdg
et der Halteraum , der durch den Musterraum überschrieben wird - was die aktuelle Zeile bedeutet , ist dann sowohl in den Griff und Musterräume - und dann wird es//
es für ein Spiel seiner zuletzt kompilierten regulären Ausdruck überprüfen -match
- und wenn es nichtmatch
es wirdp
gerintert.Dies bedeutet, dass eine Zeile nur gedruckt wird, wenn dies nicht der Fall ist, und die unmittelbar vorhergehende Zeile nicht . Sie verzichtet auch auf unnötige Auslagerungen für Sequenzen von es.
match
match
match
Wenn Sie eine Version wünschen, die eine beliebige Anzahl von Zeilen löschen kann, die nach einem auftreten
match
, wäre etwas mehr Arbeit erforderlich:... ersetzen Sie die 5 durch die Anzahl der Zeilen (einschließlich der übereinstimmenden Zeile) , die Sie entfernen möchten ...
quelle