Terminal-Minis: Dateinamen mit/ohne Pfad/Extension ausgeben
Dateinamen bestehen aus Pfad, Namen und Erweiterung - wäre doch schön, alles einzeln ansprechen zu können
Diesmal geht es ganz explizit um ein Bash-Feature - ein tolles, aber wohl eher mittel bekanntes: Parameter Expansion. Mit dieser tollen Funktion lassen sich Parameter manipulieren. Und das eben zum Beispiel, um die Bestandteile von Dateinamen - Pfad, Name, Erweiterung - separat zu nutzen.
Zunächst mal: Auch wenn es Parameter Expansion heißt, so können auch beliebige Variablen manipuliert werden. In der Praxis werden Dateien/Dateinamen meist irgendwelchen Befehlen übergeben, entweder einzeln (echo foobar.txt) oder als Stapel (echo *.txt) - meist aber beides gleichzeitig über Schleifen. Das Standardbeispiel dürfte das hier sein:
for file in dateien/*.txt; do echo $file; done
Die simple for-Schleife gibt schlicht alle TXT-Dateien im Verzeichnis dateien aus. Und um den Anschluss an das Bash-Feature zu bekommen: Der jeweilige Dateiname ist natürlich in Form der Variablen $file der Parameter für den echo-Befehl. Und eben dieser Parameter soll nun mal verändert werden. Angenommen es gibt folgende Struktur:
- Arbeitsverzeichnis
- dateien
- foo.txt
- bar.txt
- dateien
Die obige Standardschleife würde also dateien/foo.txt und dateien/bar.txt ausgeben. Was, aber, wenn Ihr foo oder txt oder aus irgendwelchen wirren Gründen dateien/foo benötigt? Hier eine Schleife, die alles ausgibt:
for file in dateien/*.txt; do
echo -e \
'Dateiname mit Pfad/Erweiterung:\t' "$file" \
'\nDateiname ohne Erweiterung:\t' "${file%.*}" \
'\nDateiname pur:\t\t\t' $(basename "${file%.*}") \
'\nErweiterung:\t\t\t' "${file##*.}" '\n'
done
Die Ausgabe:
Dateiname mit Pfad/Erweiterung: dateien/foo.txt
Dateiname ohne Erweiterung: dateien/foo
Dateiname pur: foo
Erweiterung: txt
Normalerweise sprecht Ihr solche Parameter schlicht mit $file an. Für das Expansion-Feature solltet Ihr geschweifte Klammern nutzen, also ${file}. Nötig ist das nicht, aber sonst geht auch noch der Rest an Übersichtlichkeit flöten.
Die Varianten hier:
- ${file%.*} ergibt "dateien/foobar"
- $(basename "${file%.*}" ergibt "foobar"
- ${file##*.} ergibt "txt"
Die Zeichen % und ## stehen hier quasi für "Abschneiden hinter beziehungsweise vor dem folgenden Muster", wobei das Muster schlicht aus Punkt und Freihalter-Sternchen besteht. Und basename sorgt dafür, dass der Pfad vor dem eigentlichen Dateinamen entfernt wird - und ist somit allein genutzt auch der Weg zu foobar.txt mit Erweiterung, ohne Pfad.
Das Thema Parameter Expansion gibt noch viel viel mehr her, schaut ins Handbuch. Aber den Bereich "Mini" haben wir in dieser Folge vermutlich eh schon leicht verlassen ;)
Für Terminal-Hilfe direkt im Terminal, schaut bei cli.help vorbei.
Nachtrag
Der Vollständigkeit halber hier noch die obige Schleife, aber um den puren Pfad und den Dateinamen samt Endung erweitert:
for file in dateien/*.txt; do
echo -e \
'Dateiname mit Pfad/Erweiterung:\t' "$file"\
'\nDateiname ohne Erweiterung:\t' "${file%.*}" \
'\nPfad pur:\t\t\t' "$(dirname $file)" \
'\nDatei mit Erweiterung:\t\t' "${file##*/}"\
'\nDateiname pur:\t\t\t' $(basename "${file%.*}") \
'\nErweiterung:\t\t\t' "${file##*.}"\
'\n'
done
Ergebnis:
Dateiname mit Pfad/Erweiterung: dateien/datei.txt
Dateiname ohne Erweiterung: dateien/datei
Pfad pur: dateien
Datei mit Erweiterung: datei.txt
Dateiname pur: datei
Erweiterung: txt
Aus Interesse: wurdet ihr gehackt oder woher kommt die Flut an Terminal-Texten? Die könnte man doch auch zusammenfassen?
Nee, Danke, alles gut, wir wurden nicht gehackt 😮💨
Zusammenfassen wäre hier schwierig, weil ja weder Tools komplett vorgestellt werden, noch die Arbeit im Terminal grundlegend erklärt wird. Das sind alles einzelne Aufgaben mit unterschiedlichen Tools mit der Gemeinsamkeit, dass sie via CLI bedient werden. Artikel zu Desktop-Apps müssten wir dann ja folgerichtig auch zusammenfassen. Und dann hätten wir ja nur noch zwei Artikel auf Tutonaut ;)
Aber keine Sorge, es kommen auch wieder Beiträge für die Maus und, tendenziell diese Woche, den Hintern.