C Shell(csh)にはVariable Modifiersという機能があり、パス名を含んだ変数などからファイル名や拡張子部分を取り出せます。同じことがbashでもできないか調べてみました。
cshのVariable Modifiers
cshのVariable Modifiersとは、次のような機能です。
Modifier |
意味 |
例 |
r |
ルート |
${file:r} |
e |
拡張子 |
${file:e} |
h |
ディレクトリ(Head) |
${file:h} |
t |
ファイル(Tail) |
${file:t} |
次のような簡単なシェル・スクリプトで動作を確認してみます。
#!/bin/csh
set work_dir=/home/pi/work/*
foreach f ($work_dir)
echo "--------------------------------------"
echo "original: ${f}"
echo "Root: ${f:r}" # root (without extension)
echo "Extension: ${f:e}" # extension
echo "Head(or Directory): ${f:h}" # dirname
echo "Tail(or Filename): ${f:t}" # basename
end
このシェル・スクリプトは、/home/pi/workに含まれているファイルについて、
・フルパス(Original)
・拡張子(Extension)
・ディレクトリ名(Head)
・ファイル名(Tail)
をそれぞれ表示します。
例えば、/home/pi/workに次のようなファイルとディレクトリ(main.c, readme.txt, src)があるとき
pi@raspberrypi ~/work $ pwd
/home/pi/work
pi@raspberrypi ~/work $ ls -la
total 20
drwxr-xr-x 3 pi pi 4096 Apr 24 01:22 .
drwxr-xr-x 19 pi pi 4096 Apr 24 01:43 ..
-rw-r--r-- 1 pi pi 4 Apr 24 01:20 main.c
-rw-r--r-- 1 pi pi 4 Apr 24 01:21 readme.txt
drwxr-xr-x 2 pi pi 4096 Apr 24 01:21 src
シェル・スクリプトを実行すると次の結果になります。
--------------------------------------
original: /home/pi/work/main.c
Root: /home/pi/work/main
Extension: c
Head(or Directory): /home/pi/work
Tail(or Filename): main.c
--------------------------------------
original: /home/pi/work/readme.txt
Root: /home/pi/work/readme
Extension: txt
Head(or Directory): /home/pi/work
Tail(or Filename): readme.txt
--------------------------------------
original: /home/pi/work/src
Root: /home/pi/work/src
Extension:
Head(or Directory): /home/pi/work
Tail(or Filename): src
ルートと拡張子の関係は、"ルート"."拡張子"で元のパスを表します。
bashで同じ処理をする
ここを参考にしました。##*などを使えば良いみたいです。
#!/bin/bash
work_dir=/home/pi/work/*
for f in $work_dir; do
echo "--------------------------------------"
echo "original: ${f}"
echo "Root: ${f%.*}" # everything before last '.'
echo "Extension: ${f##*.}" # everything after last '.'
echo "Head(or Directory): ${f%/*}" # everything before last '/'
echo "Tail(or Filename): ${f##*/}" # everything after last '/'
done
シェル・スクリプトを実行すると次の結果になります。
--------------------------------------
original: /home/pi/work/main.c
Root: /home/pi/work/main
Extension: c
Head(or Directory): /home/pi/work
Tail(or Filename): main.c
--------------------------------------
original: /home/pi/work/readme.txt
Root: /home/pi/work/readme
Extension: txt
Head(or Directory): /home/pi/work
Tail(or Filename): readme.txt
--------------------------------------
original: /home/pi/work/src
Root: /home/pi/work/src
Extension: /home/pi/work/src
Head(or Directory): /home/pi/work
Tail(or Filename): src
ディレクトリなどで拡張子が見つからなかった場合の結果がcshの場合と違います。cshの場合はNULLですがbashの場合は/home/pi/work/srcとフルパスになります。
basenameとdirname
ファイル名とディレクトリ名を取得するだけであれば、basenameとdirnameコマンドでも同じことができます。cshの場合は次のようなスクリプトになります。
#!/bin/csh
set work_dir=/home/pi/work/*
foreach f ($work_dir)
echo "--------------------------------------"
echo "original: ${f}"
echo "Head(or Directory): `dirname ${f}`"
echo "Tail(or Filename): `basename ${f}`"
end
bashの場合は次のようなスクリプトになります。
#!/bin/bash
work_dir=/home/pi/work/*
for f in $work_dir; do
echo "--------------------------------------"
echo "original: ${f}"
echo "Head(or Directory): `dirname ${f}`"
echo "Tail(or Filename): `basename ${f}`"
done
どちらのスクリプトも次の実行結果になります。
--------------------------------------
original: /home/pi/work/main.c
Head(or Directory): /home/pi/work
Tail(or Filename): main.c
--------------------------------------
original: /home/pi/work/readme.txt
Head(or Directory): /home/pi/work
Tail(or Filename): readme.txt
--------------------------------------
original: /home/pi/work/src
Head(or Directory): /home/pi/work
Tail(or Filename): src