Пример: Я хочу создать быструю команду для сжатия изображений (для моего файлового браузера).
...
FN="/tmp/some-image.jpg"
gm convert "$FN" -resize 50% "$(dirname $FN)/$(basename $FN .jpg/png/gif).jpg"
...
Как указать, что следует удалить более одного суффикса?
решение1
basename
требуется удалить только один суффикс и получить базовое имя (удалив компоненты каталога), которое вам в любом случае не нужно, поэтому basename
это не совсем подходящий инструмент для ваших нужд.
Традиционный инструмент для извлечения данных из строки expr
:
FN_without_extension=$(expr "x$FN" : 'x\(.*\)\.')
Но современные оболочки (такие как zsh
, bash
, ksh
, ash
, yash
, все совместимые с POSIX sh
...) имеют встроенные операторы для этого, так что в настоящее время они вам вряд ли понадобятся expr
(и лучше этого избегать, поскольку с ними связано несколько проблем).
${var%pattern}
удаляет (наименьшую) часть, соответствующую шаблону из конца$var
gm convert "$FN" -resize 50% "${FN%.*}.jpg"
Оболочки типа tcsh
или zsh
имеют операторы для удаления расширений. Zsh:
gm convert $FN -resize 50% $FN:r.jpg
( r
дляrootname).
Если вы хотите удалить только расширение jpg/png/gif, то это становится более сложным и зависимым от оболочки.
С zsh
:
gm convert $FN -resize 50% ${FN%.(jpg|png|gif)}.jpg
С ksh
:
gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"
С bash
:
shopt -s extglob
gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"
С expr
:
gm convert "$FN" -resize 50% "$(
expr \( "x$FN" : '\(.*\)\.png$' \| \
"x$FN" : '\(.*\)\.jpg$' \| \
"x$FN" : '\(.*\)\.gif$' \| "x$FN" \) : 'x\(.*\)')".jpg
(да, это запутанно, и это для того, чтобы обойти некоторые проблемы expr
).
В некоторых expr
реализациях это можно упростить до:
expr \( "x$FN" : '\(.*\)\.\(png\|jpg\|gif\)$' \| "x$FN" \) : 'x\(.*\)'
Вы также можете использовать sed
:
FN_without_ext=$(printf '%s\n' "$FN" |
sed -e '$!b' -e 's/\.png$//;t' -e 's/\.gif$//;t' -e 's/\.jpg$//')
Если вы хотите, чтобы он был нечувствителен к регистру, вы можете заменить png/gif/jpg
во всех этих решениях выше на [pP][nN][gG]...
, некоторые оболочки/инструменты также могут выполнять сопоставление без учета регистра:
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
ГНУ sed
:
FN_without_ext=$(printf '%s\n' "$FN" | sed -r '$s/\.(png|gif|jpg)$//I')
решение2
Это должно сработать? По сути, это удаление .mp3
расширений .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