Zum Inhalt springen

Pathname Expansion (Globs)

Glob-Muster (Wildcards) werden von der Shell zu einer Liste von Dateinamen expandiert, die auf das Muster passen. Das passiert vor der Ausführung des eigentlichen Befehls – das Programm sieht nur die fertige Liste, nicht das Muster.

echo macht das gut sichtbar: Es gibt einfach aus, was die Shell ihm als Argumente übergibt.

  • Ordnerbeispiele/
    • Ordnerdokumente/
    • bild.jpg
    • brief.txt
    • notizen.txt
    • skript.sh
Terminal-Fenster
echo *
# bild.jpg brief.txt dokumente notizen.txt skript.sh

Die Shell hat * expandiert und echo eine fertige Liste übergeben – als hätte man alle Namen einzeln eingetippt.

* steht für eine beliebige Folge von Zeichen (auch leer):

Terminal-Fenster
echo *.txt
# brief.txt notizen.txt
echo b*
# bild.jpg brief.txt
echo *i*
# bild.jpg brief.txt notizen.txt skript.sh

? steht für genau ein beliebiges Zeichen:

Terminal-Fenster
# Angenommen: log1.txt log2.txt log3.txt logA.txt run.sh sind vorhanden
echo log?.txt
# log1.txt log2.txt log3.txt logA.txt
echo ???.sh
# run.sh (genau 3 Zeichen vor .sh)

Eckige Klammern definieren eine Zeichenklasse – es passt genau ein Zeichen aus der angegebenen Menge:

Terminal-Fenster
# Angenommen: log1.txt log2.txt log3.txt logA.txt logB.txt sind vorhanden
echo log[13].txt
# log1.txt log3.txt (nur 1 und 3)
echo log[1-3].txt
# log1.txt log2.txt log3.txt (Bereich 1 bis 3)
echo log[!0-9].txt
# logA.txt logB.txt (! negiert: kein Zeichen aus 0-9)

Zeichenklassen funktionieren auch mit Buchstaben und gemischten Mengen:

Terminal-Fenster
# Angenommen: main.c util.c parser.h config.h sind vorhanden
echo *.[ch]
# config.h main.c parser.h util.c

Vordefinierte Klassen in der Form [:name:] stehen für ganze Zeichenkategorien:

Terminal-Fenster
# Angenommen: bericht.txt README.md logA.txt 01-intro.md 02-basics.md sind vorhanden
echo *[[:upper:]]*
# README.md logA.txt (enthält mindestens einen Großbuchstaben)
echo [[:digit:]]*
# 01-intro.md 02-basics.md (beginnt mit einer Ziffer)

Häufig verwendete POSIX-Klassen:

KlasseBedeutung
[:upper:]Großbuchstaben A-Z
[:lower:]Kleinbuchstaben a-z
[:alpha:]Alle Buchstaben
[:digit:]Ziffern 0-9
[:alnum:]Buchstaben und Ziffern
[:space:]Leerzeichen, Tab, Newline

* erfasst Verzeichnisse genauso wie Dateien – der Name erscheint ohne besondere Kennzeichnung in der Ausgabe:

Terminal-Fenster
echo *
# bild.jpg brief.txt dokumente notizen.txt skript.sh
# ^^^^^^^^^
# Verzeichnis, sieht aus wie eine Datei

Ob ein Treffer eine Datei oder ein Verzeichnis ist, entscheidet nicht der Glob, sondern der Befehl, der die Liste verarbeitet.

Dateien und Verzeichnisse, deren Name mit . beginnt, gelten unter Linux als versteckt und werden von Globs standardmäßig nicht erfasst – der Punkt muss explizit angegeben werden:

Terminal-Fenster
echo *
# bild.jpg brief.txt dokumente notizen.txt skript.sh
# (.bashrc, .profile, .ssh/ bleiben unsichtbar)
echo .*
# .bash_history .bashrc .profile .ssh
echo .b*
# .bash_history .bashrc

Wenn kein Dateiname auf das Muster passt, lässt die bash das Muster standardmäßig unverändert stehen:

Terminal-Fenster
echo *.xyz
# *.xyz ← kein Treffer: das Muster bleibt literal

Wie bei Substitutionen verhindern Anführungszeichen die Expansion:

Terminal-Fenster
echo "*.txt" # *.txt ← doppelt: kein Glob, Variablen-Substitution wirkt noch
echo '*.txt' # *.txt ← einfach: alles wörtlich
echo \*.txt # *.txt ← Backslash escaped das einzelne Zeichen

Glob-Muster sehen regulären Ausdrücken ähnlich, funktionieren aber anders:

GlobRegex-ÄquivalentBedeutung
*.*beliebig viele Zeichen
?.genau ein Zeichen
[abc][abc]ein Zeichen aus der Menge