Auflistung mit ls und regulärem Ausdruck

14

Wie kann ich Dateien mit einem Dateinamen auflisten, der mit dem letzten Zeichen und mit endet? .txt Erweiterung ?

Ich habe es versucht, ls *+([[:digit:]]).txtaber das ist wahr fürabc12.txt und abc2.txt.

Aber ich muss nur bekommen abc2.txt . Wie kann ich das machen?

Gibt es irgendeine Art von Form :digit:, die dies bewirkt?

Wir sind
quelle
2
Es sollte beachtet werden Muster ist nur gültig mit erweiterten Globbing endabled: shopt -s extglob.
donothingsuccessfully

Antworten:

19

Wie wäre es mit:

ls *[!0-9][0-9].txt

Das ! am Anfang der Gruppe ergänzt ihre Bedeutung.

Wie in den Kommentaren vermerkt, ist dies Bashs Aufgabe, versuchen Sie zB:

printf "%s\n" *[!0-9][0-9].txt
Thor
quelle
2
Beachten Sie, dass bash (ie ls) hier keine regulären Ausdrücke unterstützt. Dies sind Dateinamenausdrücke (Globbing) . Sie sehen den Unterschied bereits in Ihrem Beispiel: Hier *ist ein Platzhalter, der in regulären Ausdrücken nicht vorhanden ist, mit dem Sie .*dasselbe erreichen würden . Reguläre Ausdrücke sind viel leistungsfähiger als Globbing.
Christopher K.
2

Die Frage wurde nach regulären Ausdrücken gestellt. Bash lsunterstützt hier also keine regulären Ausdrücke. Was es unterstützt, sind Dateinamenausdrücke ( Globbing ), eine Form von Platzhaltern. Reguläre Ausdrücke sind viel leistungsfähiger.

Wenn Sie wirklich reguläre Ausdrücke verwenden möchten, können Sie folgendermaßen vorgehen find -regex:

find . -maxdepth 1 -regex '\./.*[^0-9][0-9]\.txt'

Find ist standardmäßig rekursiv, aber lsnicht. Um nur Dateien im aktuellen Verzeichnis zu finden, können Sie die Rekursion mit deaktivieren -maxdepth 1. Finden Sie Übereinstimmungen mit dem Dateinamen mit Pfad. Deshalb beginnen die Dateinamen mit, ./wenn Sie find in ausführen .. Der Regex beginnt damit umzugehen \./. Beachten Sie, dass es sich bei einem regulären Ausdruck .um ein Sonderzeichen handelt, das mit jedem Zeichen übereinstimmt. Hier wollen wir jedoch unbedingt einen Punkt. Deshalb schließen wir ihn mit einem Backslash. Wir machen dasselbe für den Punkt in .txt, da der reguläre Ausdruck sonst auch übereinstimmen würde Atxt. Die Ziffernklassen sind die gleichen wie beim Globbing, nur dass Sie ^stattdessen brauchen! zu invertieren der Zeichenklasse.

Wenn Sie die Ausgabe von erhalten möchten, lskönnen Sie -exec lswie folgt verwenden:

 find . -maxdepth 1 -regex '\./.*[^0-9][0-9]\.txt' -exec ls -lah {} \;

findunterstützt ein paar verschiedene Regex-Geschmacksrichtungen. Sie können beispielsweise Folgendes angeben -regextype:

find . -maxdepth 1 -regextype egrep -regex '\./.*[^0-9][0-9]\.txt'

Mögliche Typen sind für mich: 'findutils-default', 'awk', 'egrep', 'ed', 'emacs', 'gnu-awk', 'grep', 'posix-awk', 'posix-basic' , 'posix-egrep', 'posix-extended', 'posix-minimal-basic', 'sed' Sie können find -regextype helpherausfinden, was auf Ihrem System unterstützt wird.

Christopher K.
quelle
0

Mit den erweiterten ksh-Globs (oder bash -O extgloboder zsh -o kshglob), die Sie bereits verwenden, wäre das:

ls -d -- ?(*[![:digit:]])[[:digit:]].txt

Oder

ls -d -- !(*[[:digit:]])[[:digit:]].txt

Wenn du weiter passen willst a1.txt und2.txt doch nicht a12.txtnoch12.txt .

Beachten Sie jedoch, dass in ksh und bash (sofern Sie nicht die failglobOption zum Abrufen eines ähnlichen Verhaltens wie zsh festlegen ) das Muster wörtlich an übergeben lswird , wenn dieses Muster keiner Datei entspricht , und wenn diese (seltsam benannte) Datei passiert vorhanden ist, wird es aufgelistet ls, obwohl es nicht mit dem Muster selbst übereinstimmt.

Um dies einzuschließen .2.txt, setzen Sie die dotglobOption in bash, fügen Sie das (D)Glob-Qualifikationsmerkmal in hinzu zshoder setzen SieFIGNORE auf !(.|..)in ksh93.

Stéphane Chazelas
quelle