例: 画像を縮小する簡単なコマンドを作成したい (ファイルブラウザ用)。
...
FN="/tmp/some-image.jpg"
gm convert "$FN" -resize 50% "$(dirname $FN)/$(basename $FN .jpg/png/gif).jpg"
...
複数のサフィックスを削除するように指定するにはどうすればよいでしょうか?
答え1
basename
削除するには 1 つのサフィックスのみが必要で、ベース名 (ディレクトリ コンポーネントを削除) が提供されますが、これはいずれにしても必要ありません。そのため、basename
実際にはニーズに適したツールではありません。
文字列からデータを抽出するための従来のツールは次のとおりですexpr
。
FN_without_extension=$(expr "x$FN" : 'x\(.*\)\.')
しかし、最近のシェル ( zsh
、、、、、など、すべて POSIX 準拠) にはそのための組み込み演算子があるため、現在ではほとんど必要ありません(いくつかの問題があるためbash
、使用を避けるのが最善です)。ksh
ash
yash
sh
expr
${var%pattern}
末尾からパターンに一致する(最小の)部分を削除します$var
gm convert "$FN" -resize 50% "${FN%.*}.jpg"
tcsh
またはのようなシェルには、zsh
拡張子を削除する演算子があります。 Zsh:
gm convert $FN -resize 50% $FN:r.jpg
(r
のためにルート名)。
拡張子を削除する場合、それが 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
GNU 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