Extrahieren von Dateibasisnamen ohne Pfad und Erweiterung in der Bash

Bei Dateinamen wie diesen:

/the/path/foo.txt
bar.txt

hoffe ich zu bekommen:

foo
bar

Warum funktioniert das nicht?

#!/bin/bash

fullfile=$1
fname=$(basename $fullfile)
fbname=${fname%.*}
echo $fbname

Wie's ist der richtige Weg?

Lösung

Sie müssen den externen Befehl basename nicht aufrufen. Stattdessen können Sie die folgenden Befehle verwenden:

$ s=/the/path/foo.txt
$ echo ${s##*/}
foo.txt
$ s=${s##*/}
$ echo ${s%.txt}
foo
$ echo ${s%.*}
foo

Beachten Sie, dass diese Lösung in allen neueren (nach 2004) POSIX-kompatiblen Shells funktionieren sollte (z.B. bash, dash, ksh, etc.).

Quelle: Shell Command Language 2.6.2 Parametererweiterung

Mehr zu bash String Manipulationen: http://tldp.org/LDP/LG/issue18/bash.html

Kommentare (15)

Der Befehl basename hat zwei verschiedene Aufrufe; in einem geben Sie nur den Pfad an, in diesem Fall erhalten Sie die letzte Komponente, während Sie im anderen Fall auch ein Suffix angeben, das entfernt wird. Sie können also Ihren Beispielcode vereinfachen, indem Sie den zweiten Aufruf von basename verwenden. Achten Sie außerdem auf die korrekte Zitierweise:

fbname=$(basename "$1" .txt)
echo "$fbname"
Kommentare (4)

Verwenden Sie den Befehl basename. Die Manpage dazu finden Sie hier: http://unixhelp.ed.ac.uk/CGI/man-cgi?basename

Kommentare (1)