ls ignorieren "keine Übereinstimmungen"

8

Ich möchte alle Dateien in einem Ordner zur Liste genannt , foldernamedass die Erweiterung hat test, atestoder btest.

Mein unmittelbarer Gedanke war zu rennen ls ./foldername/*.{a,b,}test

Dies funktioniert einwandfrei, es sei denn, die Erweiterung enthält nichts atest. In diesem Fall wird der Fehler angezeigt zsh: no matches found: ./foldername/*.atest.

Kann ich diesen Fehler einfach ignorieren und die vorhandenen Dateien drucken?

Ich brauche das, um sowohl in ZSH als auch in BASH zu arbeiten.

Jonathan Hodgson
quelle
3
Standardfehler umleiten an /dev/null?
DopeGhoti

Antworten:

9

Es kann am besten sein, dies zu tun mit find:

find ./foldername -maxdepth 1 -name '*.atest' -o -name '*.btest' -o -name '*.test'
John Moon
quelle
1
vielleicht mit einem -maxdepth 1, um das lsVerhalten näher zu emulieren
Jeff Schaller
4
@ JeffSchaller, beachte, dass -maxdepthes sich um eine GNU-Erweiterung handelt. Anmerkung 3 andere Unterschiede zu Globs: Enthält findversteckte Dateien, sortiert die Liste nicht und stimmt nicht mit Dateinamen überein, die Bytes enthalten, die keine gültigen Zeichen bilden (wie $'St\xe9phane.atest'in einem UTF-8-Gebietsschema)
Stéphane Chazelas,
11

Im

ls -d ./foldername/*.{a,b,}test

{a,b,...} ist kein Glob-Operator, das ist eine Klammererweiterung, die zuerst erweitert wurde auf:

ls -d ./foldername/*.atest ./foldername/*.btest ./foldername/*.test

Und jeder Glob wird einzeln erweitert, und wenn ein Glob nicht übereinstimmt, wird der Befehl wie erwartet abgebrochen zsh(oder fish; in bashbenötigen Sie die failglobOption, um ein ähnliches Verhalten zu erzielen).

Hier möchten Sie einen einzelnen Glob verwenden, der mit all diesen Dateien übereinstimmt, und den Befehl nur abbrechen, wenn dieser eine Glob keiner Datei entspricht:

ls -d ./foldername/*.(a|b|)test

Sie möchten nicht verwenden nullglob, als ob keiner der Globs übereinstimmt, es würde lsohne Argumente ausgeführt, also listen Sie das aktuelle Verzeichnis auf. cshnullglobist in dieser Hinsicht besser, da nicht übereinstimmende Globs entfernt werden, der Befehl jedoch abgebrochen wird, wenn nicht alle Globs übereinstimmen.

Sie würden nicht verwenden wollen nonomatch, da dies Ihnen das gebrochene Verhalten geben bashwürde, dessen Schande eine Schande wäre.

Für eine Glob-Alternative, die in beiden zshund funktioniert bash, können Sie die ksh-Globs ( set -o kshglobin zshund shopt -s extglobin bash) verwenden.

Dann würden Sie tun:

ls -d ./foldername/*.@(a|b|)test

oder:

ls -d ./foldername/*.?([ab])test

Fügen Sie die failglobOption hinzu bash, um zu vermeiden, dass der Globus buchstäblich an übergeben wird, lswenn er nicht übereinstimmt.

Siehe Warum ist nullglob nicht die Standardeinstellung? für mehr Informationen.

Stéphane Chazelas
quelle
Ich bin nicht sicher, warum dies eine Anforderung des OP ist, aber gibt es einen Extglob, der sowohl in bash als auch in zsh dafür funktioniert? Ich musste ?(...)oder +(...)für Bash verwenden.
Jeff Schaller
@ JeffSchaller, siehe bearbeiten
Stéphane Chazelas