ファイル名(拡張子なし)と拡張子を別々に取得したい。
今のところ見つけた一番の解決策は
NAME=`echo "$FILE" | cut -d'.' -f1`
EXTENSION=`echo "$FILE" | cut -d'.' -f2`
これは、ファイル名に複数の .
文字が含まれている場合には動作しないので、間違っています。例えば、a.b.js
とすると、a.b
とjs
ではなく、a
とb.js
と判断してしまいます。
これはPythonでは次のようにして簡単に行うことができます。
file, ext = os.path.splitext(path)
しかし、できればこのためにPythonのインタプリタを起動したくはありません。
何か良いアイデアはありませんか?
まず、ファイル名をパスなしで取得します。
filename=$(basename -- "$fullfile")
extension="${filename##*.}"
filename="${filename%.*}"
また、パスの最後の「.」ではなく「/」に注目することで、予測できないファイル拡張子があっても動作するはずです。
filename="${fullfile##*/}"
ドキュメントを確認してみてください。
~% FILE="example.tar.gz"
~% echo "${FILE%%.*}"
example
~% echo "${FILE%.*}"
example.tar
~% echo "${FILE#*.}"
tar.gz
~% echo "${FILE##*.}"
gz
詳細は,Bashのマニュアルのシェルパラメータの拡張を参照してください。
pax> echo a.b.js | sed 's/\.[^.]*$//'
a.b
pax> echo a.b.js | sed 's/^.*\.//'
js
は問題なく動作しますので、そのまま使用できます。
pax> FILE=a.b.js
pax> NAME=$(echo "$FILE" | sed 's/\.[^.]*$//')
pax> EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
pax> echo $NAME
a.b
pax> echo $EXTENSION
js
ちなみに、コマンドは以下のように動作します。
NAMEのコマンドは、
"."の文字の後に、
"."ではない任意の数の文字が行末まで続くと、何もない状態に置換します(つまり、最後の
"."`から行末までのすべてを削除します)。これは基本的に、正規表現のトリックを使ったgreedyではない置換です。
EXTENSIONのコマンドは、行頭の
"."` に続く任意の数の文字を、何もない状態に置換します(つまり、行頭から最後のドットまでのすべてを削除します)。これは greedy な置換で、デフォルトの動作です。