Schließen Sie ein Muster vom Glob-Match aus

53

Ich habe mehrere Dateien mit dem gleichen Basisdateinamen. Ich möchte alle bis auf einen entfernen

foo.org #keep
foo.tex #delete
foo.fls #delete
foo.bib #delete
etc

Wenn ich keinen behalten müsste, könnte ich ihn gebrauchen rm foo.*.

TLDP zeigt ^, dass eine Übereinstimmung annulliert wird . Durch Versuch und Irrtum konnte ich das herausfinden

rm foo.*[^org]

tut was ich brauche, aber ich verstehe die Syntax nicht wirklich.

Auch wenn dies in meinem Anwendungsfall keine Einschränkung darstellt, denke ich, dass dieses Muster auch foo.ound ignoriert foo.or. Wie funktioniert dieses Muster und wie würde ein Globus, der ignoriert, nur foo.org aussehen?

jake
quelle
1
Als Ergänzung zu erwähnen , dass es @glen beantworten Wert rm foo.*[^org]entfernt alle Dateien , die letzten Zeichen sind weder o, roder g, so foo.foowürde entweder nicht überein.
Jimmy
Sie verwenden eine Regular Expression. Sie sollten mit Ihren Gruppierungszeichen vorsichtig sein. Mit Hilfe von Klammern haben Sie eine Zeichenklasse angegeben, die bedeutet, dass Sie alle Dateien löschen, die eine Erweiterung mit den Buchstaben haben o, roder gin beliebiger Reihenfolge. Verwenden Sie Klammern, um eine Gruppe zu erstellen und die Reihenfolge der Zeichen beizubehalten.
Mr. Mascaro
3
@ jbarker2160 - das ist kein regulärer Ausdruck, sondern wird allgemein als Glob (oder Dateinamenmuster ) bezeichnet. Dies ist mehr oder weniger eine Teilmenge eines regulären Ausdrucks. Weitere Informationen finden Sie im Abschnitt zur Mustererkennung auf der bash-Manpage. Sein Muster foo.*[^org]stimmt mit jedem Dateinamen überein, der foo.mit einem oder mehreren Zeichen nach dem Punkt beginnt, wobei das letzte Zeichen nicht o, r oder g ist. Also würde es passen foo.orb, aber nicht foo.orgoder foo.oroder foo.o. Die Antwort von GlennJackman zeigt, wie erweiterte Mustervergleichsfunktionen zum Negieren einer Übereinstimmung aktiviert werden.
Johnny

Antworten:

23

In Bash können Sie auch verwenden GLOBIGNORE="*.org"; rm -i foo*.

Und unset GLOBIGNOREwenn es fertig ist.

Es ist nicht wirklich besser als shopt -s extglob, aber ich finde es leichter, mich zu erinnern.

mivk
quelle
5
@ Ruslan Das funktioniert nicht. Sie sollten tun( GLOBIGNORE="*.org"; rm -i foo* )
DBedrenko
3
Hinweis: Wenn Sie die Liste der ignorierten GLOBIGNORE="*foo*:*bar*"
Elemente
7

Eine Pfeife kann?

ls * | grep -v "foo.org" | xargs -I {} echo {}

(Natürlich möchten Sie das Echo in der letzten Kette durch rm ersetzen.)

Adobe
quelle
Nützlich bei Bedarf in nur einer Zeile.
Bruceskyaus
1
Einfacher zu merken (für mich mache ich so etwas oft) und erlaubt komplexere Verarbeitung zu booten :)
Drevicko
1
ls -1sollte zuverlässiger sein, um sicherzustellen, dass alle Dateien grepseparat behandelt werden
MichaelChirico
0

OP war sehr nah:

rm foo.*[^o][^r][^g]

in diesem Fall ist das *jedoch unnötig.

MrMas
quelle