複数の可能なサフィックスの削除

複数の可能なサフィックスの削除

例:画像を縮小するクイックコマンドを作成したい(私のファイルブラウザ用)。

...
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すべてPOSIX互換...)には演算子が組み込まれているので、最近はほとんど必要ありません(いくつbashかの問題があるので避けることをお勧めします)。kshashyashshexpr

${var%pattern}

最後から(最も小さい)部分一致パターンを削除します。$var

gm convert "$FN" -resize 50% "${FN%.*}.jpg"

シェルは拡張を削除するためにOR演算子tcshを好みます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

グヌsed

 FN_without_ext=$(printf '%s\n' "$FN" | sed -r '$s/\.(png|gif|jpg)$//I')

おすすめ記事