Zeile löschen, wenn zwei Muster in derselben Zeile gefunden werden

Zeile löschen, wenn zwei Muster in derselben Zeile gefunden werden

Ich möchte eine Zeile aus einer Textdatei ( input.txt) löschen, wenn zwei Muster ( string1und string2) auf derDasselbeZeile, mit sed.

Ich versuche: sed -i "/\b\(string1\|string2\)\b/d" input.txt, aber dadurch werden Zeilen gelöscht, string1die ODER enthalten string2.

Antwort1

sed -i "/string1.*string2\|string2.*string1/d" input.txt

Dadurch werden alle Zeilen gelöscht, in denen string1 vor string2 steht ODER string2 vor string1 steht. Damit die Zeile gelöscht wird, müssen beide Zeichenfolgen in beliebiger Reihenfolge in der Zeile stehen.

Antwort2

sed -ie '/string1/!b' -e '/string2/d' file.txt

Dadurch werden Zeilen gelöscht, die sowohl als string1auch enthalten string2, unabhängig von der Reihenfolge (es kann sogar zu Überschneidungen kommen, wie etwa bei der Suche nach foobarin barbazin einer Zeile, die enthält foobarbaz).

-ioben ist eine GNU-Erweiterung. Eine weitere GNU-spezifische Lösung¹:

awk -i /usr/share/awk/inplace.awk '!(/string1/ && /string2/)' file.txt

Für den mobilen Einsatz würden Sie wahrscheinlich perlFolgendes verwenden:

perl -ni -e 'print unless /string1/ && /string2/'

¹verwende nicht-i inplaceas versucht zunächst, die Erweiterung (as oder ) aus dem aktuellen Arbeitsverzeichnis gawkzu laden , wo jemand Malware platziert haben könnte. Der Pfad der mit gelieferten Erweiterung kann je nach System unterschiedlich sein, siehe die Ausgabe voninplaceinplaceinplace.awkinplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

Antwort3

Verwenden vonRaku(früher bekannt als Perl_6)

~$ raku -ne '.put unless .match(/ foobar / & / barbaz / ) ;'   file

ODER

~$ raku -ne '.put unless grep({ / foobar / & / barbaz / }, $_ ) ;'   file

Oben sind zwei allgemeine Möglichkeiten aufgeführt, die Aufgabe des OP mit Raku zu erfüllen. Beachten Sie, grepdass Raku Perl ähnelt grep, außer dass nach dem Block ein Komma erforderlich ist. Sie können .grepstattdessen auch den Methodenaufruf verwenden und müssen sich nicht um das Schreiben $_in die Klammern kümmern.

Beide Codebeispiele oben löschen Zeilen, die zwei Zeichenfolgen enthalten,unabhängig von der Reihenfolge UND unabhängig davon, ob sich die Zeichenfolgen überschneiden.Zum Beispiel:

Beispieleingabe:

1  foo
2  bar
3  baz
4  foobar
5  foobaz
6  barbaz
7  foobar foobaz
8  foobaz barbaz
9  foobar barbaz
10 foobar foobaz barbaz
11 foobaz barbaz foobar
12 barbaz foobar foobaz
13 foobarbaz

Beispielausgabe (entweder der Codebeispiele oben):

1  foo
2  bar
3  baz
4  foobar
5  foobaz
6  barbaz
7  foobar foobaz
8  foobaz barbaz

Der obige Code löscht die Zeilen 9 bis 13, einschließlich Zeile 13, foobarbazdie die Überlappung von string1 und string2 enthält. Wenn Sie Zeichenfolgen löschen müssen, die in einer bestimmten Reihenfolge (und ohne Überlappung) erscheinen, kann Raku das auch tun:

~$ raku -ne '.put unless m/foobar .* barbaz/;'  file

Oben werden die Zeilen 9 und 10 entfernt: foobar barbazund foobar foobaz barbaz.


Beachten Sie, dass Sie mit Raku-Regexendürfenerkennt zwei sich überschneidende Zeichenfolgen mit dem Parameter/Adverb :overlap(oder :ov). Siehe ersten Link unten.


https://docs.raku.org/language/regexes#Overlap
https://docs.raku.org/language/regexes
https://raku.org

verwandte Informationen