Ich habe 3 Verzeichnisse im aktuellen Pfad.
$ls
a_0db_data a_clean_0db_data a_clean_data
$ls a_*_data
a_0db_data:
a_clean_0db_data:
a_clean_data:
$ls a_[a-z]*_data
a_clean_0db_data:
a_clean_data:
Ich habe erwartet, dass der letzte ls-Befehl nur übereinstimmt a_clean_data
. Warum passte es auch zum Inhalt 0
?
bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
bash
regular-expression
wildcards
user13107
quelle
quelle
a_*_data
eine dieser Dateien übereinstimmt, hat Sie also nicht überrascht?Antworten:
Das
[a-z]
Teil stimmt nicht mit der Zahl überein. es ist das*
. Möglicherweise sind Shell- Globbing und reguläre Ausdrücke verwirrend .Tools wie
grep
verschiedene Aromen von regulären Ausdrücken (nehmen Grundstandardmäßig für längere, für Perl regex )-E
-P
ZB (
-v
invertiert die Übereinstimmung)Wenn Sie einen Bash-Regex verwenden möchten, finden Sie hier ein Beispiel zum Testen, ob die Variable
$ref
eine Ganzzahl ist:quelle
Das Problem ist also: Warum passt
a_[a-z]*_data
dasa_clean_0db_data
?Dies kann in vier Teile unterteilt werden:
a_
Entspricht dem Beginn vona_clean_0db_data
undclean_0db_data
muss abgeglichen werden[a-z]
Stimmt mit jedem Zeichen im Bereich übereina-z
(z. B.c
) undlean_0db_data
muss abgeglichen werden*
Stimmt mit einer beliebigen Anzahl von Zeichen überein, zlean_0db
_data
passt zum Trailing_data
In regulären Ausdrücken
[a-z]*
würde eine beliebige Anzahl von Zeichen (einschließlich Null) im Bereich von a..z bedeuten , aber Sie haben es mit Shell- Globbing zu tun, nicht mit regulären Ausdrücken.Wenn Sie reguläre Ausdrücke wünschen, haben einige
find
Implementierungen ein-regex
Prädikat dafür:Das
-maxdepth
ist nur hier, um die Suchergebnisse auf den Ordner zu beschränken, in dem Sie sich befinden. Der reguläre Ausdruck entspricht dem gesamten Dateinamen, daher habe ich ein hinzugefügt^.*/
, um den Pfad-Teil abzugleichenquelle
*
In Shell-Mustern werden 0 oder mehr Zeichen gefunden. Es ist nicht zu verwechseln mit dem*
Operator für reguläre Ausdrücke, der 0 oder mehr des vorhergehenden Atoms bedeutet .*
In grundlegenden Shell-Mustern gibt es kein Äquivalent zu regulären Ausdrücken . Verschiedene Shells haben dafür jedoch Erweiterungen.ksh
hat*(something)
:Sie können das gleiche
bash
mitshopt -s extglob
oderzsh
mit habensetopt kshglob
:In
zsh
mitextendedglob
aktiviert#
ist gleichbedeutend mit regexp*
:In neueren Versionen von
ksh93
können Sie auch reguläre Ausdrücke in Globs verwenden. Hier mit erweiterten regulären Ausdrücken:Beachten Sie, dass
[a-z]
je nach aktuellem Gebietsschema unterschiedliche Übereinstimmungen vorliegen. Es entspricht im Allgemeinen nur den 26a
bisz
latin nicht-Umlaut imC
locale. In anderen Gebietsschemata ist die Übereinstimmung im Allgemeinen größer und ergibt nicht immer einen Sinn. Möglicherweise bevorzugen Sie es, einen Buchstaben in Ihrem Gebietsschema zu finden[[:alpha:]]
.quelle
[a-z]
mehr Übereinstimmungen geben, als die 26 Buchstaben im Gebietsschema C übereinstimmen? Woran ich mich erinnere, als ich dies das letzte Mal angeschaut habe, hatten alle Codierungen, die praktisch in Unix-Varianten verwendet wurden, ISO-646 als Basis (dann wurden die oberen 128 Codes anders verwendet, direkt für Zeichen in Codierungen wie der ISO-8859-X, kombiniert in Kodierungen wie UTF-8 oder die EUC-Familie). Sogar AIX hatte keine EBCDIC-Ländereinstellungen (zumindest so, wie sie mir zur Verfügung standen). Ich erinnere mich, dass ich versucht habe herauszufinden, ob POSIX / UNIX-Standards dies verlangten, aber ich erinnere mich nicht an das Ergebnis.[a-z]
schließt im Allgemeinené
oderí
(aber nicht notwendigerweiseź
) an den Orten ein, an denen der Zeichensatz sie hat, ob der Codepunkt in dieser Codierung zwischen dem von a und z liegt oder nicht. Nur das Gebietsschema C garantiert eine Sortierreihenfolge basierend auf dem Codepunktwert. Weitere Informationen finden Sie in dieser anderen Antwort .