Passender n-Buchstaben-Dateiname mit ls

Passender n-Buchstaben-Dateiname mit ls

Ich verwende den lsBefehl in Bash und versuche, alle Dateien oder Verzeichnisse der Länge n zu finden. Nehmen wir an, n = 5

Mein Befehl ist:

ls ?????

Dies würde jedoch auch Zeichen einschließen, die keine Buchstaben sind, wie z. B. Punkte. Die folgenden Dateien würden beispielsweise übereinstimmen:

ab.cd    
abd.c

Ich möchte nur Dateien abgleichen, deren Namen aus 5 Buchstaben oder Zahlen bestehen:

five1
five2    
five3

Aber nicht

abc.d    
ab.cd    
a.bcd

Wie kann ich meinen Befehl ändern?

Antwort gefunden:

ls [a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]

Ich habe die Antwort gefunden, aber wie kann ich es weniger hässlich machen?

Antwort1

Beachten Sie, dass lsdiese Globs nicht von interpretiert werden. Diese Globs werden von Ihrer Shell in eine Liste von Dateinamen erweitert, die als Argumente an übergeben wird ls. Verschiedene Shells haben unterschiedliche Globbing-Fähigkeiten. bashhat einige Erweiterungen gegenüber Standard-Globs (entlehnt von ksh88und aktiviert mit shopt -s extglob), ist aber immer noch im Vergleich zu Shells wie zshoder eingeschränkt ksh93.

Mit zsh:

setopt extendedglob
ls -d [[:alnum:]](#c5)

ksh93:

ls -d {5}([[:alnum:]])

oder:

ls -d {5}(\w) # (\w includes underscore in addition to alnums)

oder, wenn Sie erweiterte reguläre Ausdrücke verwenden möchten:

ls -d ~(E)^[[:alnum:]]{5}$

Mit bashoder anderen POSIX-Shells, die keine entsprechenden Globbing-Operatoren haben, müssen Sie Folgendes tun:

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

Beachten Sie, dass [[:alnum:]]alle alphabetischen Zeichen der aktuellen Ländereinstellung (nicht nur lateinische Alphabete, geschweige denn das englische) und 0123456789(und möglicherweise andere Arten von Ziffern) eingeschlossen sind. Wenn Sie die Buchstaben des englischen Alphabets möchten, benennen Sie die Zeichen einzeln:

c='[0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'
unset -v IFS
ls -d $c$c$c$c$c

Oder verwenden Sie das Gebietsschema C:

(export LC_ALL=C
ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]])

Antwort2

ls -q | grep -Ex '[[:alnum:]]{5}'

Antwort3

lsWenn Sie die Funktion auf die von Ihnen genannte Weise verwenden möchten , sollten Sie die -dOption verwenden. Andernfalls wird dieInhaltvon irgendwelchenVerzeichnisse deren Namen aus fünf Buchstaben und/oder Ziffern bestehen, anstatt die Namen selbst aufzulisten. Sie können auch

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

aber das ist genauso viel Tipparbeit wie die Antwort, die Sie jetzt haben.

Auch wenn Sie nichtbrauchenlsUm in Ihrem Befehl zu verwenden , könnten Sie verwenden

echo [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

Dadurch werden alle Übereinstimmungen in einer Zeile aufgelistet, oder

printf "%s\n" [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][:alnum:]]

Dadurch werden sie in separaten Zeilen aufgelistet.

Antwort4

Bauen Sie den Ausdruck in einer Variablen auf:

 e=""; for m in $(seq 1 5); do e="$e[A-Za-z0-9]"; done

Fügen Sie es in eine Funktion ein, damit es schick/wiederverwendbar ist:

 alnumglob() {
    local e=""
    for m in $(seq 1 $1) ; do e="$e[A-Za-z0-9]"; done
    echo "$e"
 }

 ls -ld $(alnumglob 5)

verwandte Informationen