Beispiel: Ich möchte einen Schnellbefehl zum Verkleinern von Bildern erstellen (für meinen Dateibrowser).
...
FN="/tmp/some-image.jpg"
gm convert "$FN" -resize 50% "$(dirname $FN)/$(basename $FN .jpg/png/gif).jpg"
...
Wie kann ich angeben, dass mehr als ein Suffix entfernt werden soll?
Antwort1
basename
muss nur ein Suffix entfernt werden und gibt den Basisnamen zurück (entfernt die Verzeichniskomponenten), den Sie dort sowieso nicht haben möchten. Es basename
ist also nicht wirklich das richtige Tool für Ihren Bedarf.
Das herkömmliche Tool zum Extrahieren von Daten aus einem String ist expr
:
FN_without_extension=$(expr "x$FN" : 'x\(.*\)\.')
Aber moderne Shells (wie zsh
, bash
, ksh
, ash
, yash
, alle POSIX-kompatibel sh
...) haben integrierte Operatoren dafür, sodass Sie es expr
heutzutage kaum noch brauchen (und es sollte am besten vermieden werden, da es einige Probleme mit sich bringt).
${var%pattern}
entfernt den (kleinsten) Teil, der dem Muster entspricht, vom Ende$var
gm convert "$FN" -resize 50% "${FN%.*}.jpg"
Shells mögen tcsh
oder zsh
haben Operatoren zum Entfernen von Erweiterungen. Zsh:
gm convert $FN -resize 50% $FN:r.jpg
( r
fürStammname).
Wenn Sie die Erweiterung nur entfernen möchten, wenn es sich um eine JPG-, PNG- oder GIF-Erweiterung handelt, wird dies komplizierter und hängt von der Shell ab.
Mit zsh
:
gm convert $FN -resize 50% ${FN%.(jpg|png|gif)}.jpg
Mit ksh
:
gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"
Mit bash
:
shopt -s extglob
gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"
Mit expr
:
gm convert "$FN" -resize 50% "$(
expr \( "x$FN" : '\(.*\)\.png$' \| \
"x$FN" : '\(.*\)\.jpg$' \| \
"x$FN" : '\(.*\)\.gif$' \| "x$FN" \) : 'x\(.*\)')".jpg
(ja, das ist kompliziert und soll einige der Probleme von umgehen expr
).
Bei einigen expr
Implementierungen kann es wie folgt vereinfacht werden:
expr \( "x$FN" : '\(.*\)\.\(png\|jpg\|gif\)$' \| "x$FN" \) : 'x\(.*\)'
Sie könnten auch verwenden sed
:
FN_without_ext=$(printf '%s\n' "$FN" |
sed -e '$!b' -e 's/\.png$//;t' -e 's/\.gif$//;t' -e 's/\.jpg$//')
Wenn Sie die Groß-/Kleinschreibung nicht berücksichtigen möchten, können Sie png/gif/jpg
in allen oben genannten Lösungen das durch ersetzen [pP][nN][gG]...
. Einige Shells/Tools können die Groß-/Kleinschreibung auch nicht berücksichtigen:
zsh
:
setopt extendedglob
FN_without_ext=${FN%.(#i)(gif|png|jpg)}
ksh93
:
FN_without_ext=${FN%.~(i:gif|png|jpg)}
bash
:
shopt -s nocasematch
LC_ALL=C
if [[ $FN =~ (.*)\.(gif|png|jpg)$ ]]; then
FN_without_ext=${BASH_REMATCH[1]}
else
FN_without_ext=$FN
fi
GNU sed
:
FN_without_ext=$(printf '%s\n' "$FN" | sed -r '$s/\.(png|gif|jpg)$//I')
Antwort2
Das sollte funktionieren? Im Grunde werden dabei .mp3
Erweiterungen entfernt .wav
:
$ basename -s .wav $(basename -s .mp3 'some_file.mp3')
some_file
$ basename -s .wav $(basename -s .mp3 'some_file.wav')
some_file
$ basename -s .wav $(basename -s .mp3 'some_file.rs')
some_file.rs