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

Probleme mit regulären Ausdrücken in Bash:[^negate] scheint nicht zu funktionieren

Sind Sie sicher, was Sie wollen? Wenn Sie ls /directory | grep '[^term]' ausführen Sie suchen im Wesentlichen nicht nach den Buchstaben t e r m. Das heißt, wenn eine Datei andere Buchstaben in ihrem Namen hat, erscheint sie trotzdem in der Ausgabe von ls . Nehmen Sie zum Beispiel das folgende Verzeichnis:

$ ls
alpha  brave  bravo  charlie  delta

Wenn ich jetzt ls |grep '^[brav]' ausführe Ich bekomme folgendes:

$ ls |grep '^[brav]'
alpha
brave
bravo

Wie Sie sehen können, habe ich nicht nur brave erhalten und bravo Ich habe auch alpha weil die Zeichenklasse [] erhält jeden Buchstaben von dieser Liste.

Folglich, wenn ich ls |grep '[^brav]' ausführe Alle Dateien, die die Zeichen b r a v nicht enthalten, bekomme ich irgendwo im Namen.

$ ls |grep '[^brav]'
alpha
bravo
brave
charlie
delta

Wenn Sie bemerken, dass es die gesamte Verzeichnisliste enthielt, weil alle Dateien mindestens eine hatten Buchstabe, der nicht in der Zeichenklasse enthalten war.

Wie Kanvuanza sagte, um nach der Umkehrung von "term" zu suchen, im Gegensatz zu den Zeichen t e r m Sie sollten dies mit grep -v tun .

Zum Beispiel:

$ ls |grep -v 'brav'
alpha
charlie
delta

Auch wenn Sie die Dateien, die irgendwelche Zeichen in der Klasse haben, nicht wollen, verwenden Sie grep -v '[term]' . Dadurch werden keine Dateien angezeigt, die eines dieser Zeichen enthalten. (Antwort von Kanvuanza)

Zum Beispiel:

$ ls |grep -v '[brav]'

Wie Sie sehen, wurden keine Dateien aufgelistet, da alle Dateien in diesem Verzeichnis mindestens einen Buchstaben dieser Klasse enthielten.

Nachtrag:

Ich wollte hinzufügen, dass es mit PCRE möglich ist, nur Regex zu verwenden, um mit negierten Ausdrücken herauszufiltern. Dazu würden Sie etwas verwenden, das als negative Look-Ahead-Regex bekannt ist:(?!<regex>) .

Wenn Sie also das obige Beispiel verwenden, können Sie so etwas tun, um die gewünschten Ergebnisse zu erhalten, ohne grep zu verwenden Flaggen.

$ ls | grep -P '^(?!brav)'
alpha
charlie
delta

Um diese Regex zu dekonstruieren, passt sie zuerst auf den Anfang einer Zeile ^ und sucht dann nach Zeichenfolgen, die nicht mit brav übereinstimmen danach folgen. Nur alpha , charlie , und delta übereinstimmen, sodass nur diese gedruckt werden.


Ich vermute, dass grep -v Flagge macht was du willst. Aus der Manpage:

-v, --invert-match
    Invert the sense of matching, to select non-matching lines.

Sie können ls /directory | grep -v [term] verwenden nicht übereinstimmende Zeilen zu drucken.


Linux
  1. Reguläre Ausdrücke:Alles zusammenziehen

  2. Bash + Name durch regulären Ausdruck überprüfen?

  3. grep-Grundlagen

  4. 6 Beispiele für bedingte Bash-Ausdrücke ( -e, -eq, -z, !=, [, [[ ..)

  5. Bei der Installation der Rust-Toolchain in Docker funktioniert der Bash-Befehl „source“ nicht

Bash-Sequenzausdruck (Bereich)

Reguläre Ausdrücke in Grep (Regex)

LD_LIBRARY_PATH scheint nicht zu funktionieren

Warum funktioniert `\d` nicht in regulären Ausdrücken in sed?

Regulärer Ausdruck zum Auffinden doppelter Zeichen in Bash

Regulärer Ausdruck mit sed