Mehrere mögliche Suffixe entfernen

Mehrere mögliche Suffixe entfernen

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

basenamemuss nur ein Suffix entfernt werden und gibt den Basisnamen zurück (entfernt die Verzeichniskomponenten), den Sie dort sowieso nicht haben möchten. Es basenameist 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 exprheutzutage 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 tcshoder zshhaben Operatoren zum Entfernen von Erweiterungen. Zsh:

gm convert $FN -resize 50% $FN:r.jpg

( rfü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 exprImplementierungen 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/jpgin 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 .mp3Erweiterungen 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

verwandte Informationen