例題 2自分のホームディレクトリ以下(サブディレクトリも含む)に存在する全ての C ソースファイル(拡張子 .c)に対し,その名前の一覧を表示するシェルスクリプト clist.sh を作りなさい. ただし,各ソースファイル名の拡張子(末尾の .c)は取り除いて出力すること.解答例
list=$(find ~ -name "*.c")
for name in $list
do
echo ${name%.c}
done
解説まず,find コマンドを使って自分のホームディレクトリ以下に存在する全ての C ソースファイル(拡張子 .c)をリストアップしている.試しに
find ~ -name "*.c"
を実行してみるとよい.
これは自分のホームディレクトリ(~)以下で名前が *.c に合致 するものだけを表示するという動きをする.
ここでポイントなのは,
その実行結果をシェル変数 list に代入している
ことである.
list=$(find ~ -name "*.c")
for name in $list
do
echo ${name%.c}
done
次に,その find の実行結果(変数 list)を
for 文のリストに利用している.
ここでもう一つのポイントは
list=$(find ~ -name "*.c")
for name in $list
do
echo ${name%.c}
done
という具合いに,変数 name に少し修飾が施されている点である.
${name%.c}
という具合いに % マークを付けて書くと,
変数 name の内容のうち,
指定された文字列を末尾から削除
されたものが使われるという働きがある.
(参考)
(例)次のスクリプトを考える:
aaa=/usr/local/bin/mule
echo "(1) $aaa"
echo "(2) ${aaa#/*/}"
echo "(3) ${aaa##/*/}"
echo "(4) ${aaa%/*/}"
echo "(5) ${aaa%%/*/}"
これを実行すると
(1) /usr/local/bin/mule
(2) local/bin/mule
(3) mule
(4) /usr/local/bin/mule
(5) /usr/local/bin/mule
となる.
(2) ,(3) は先頭から /*/ というパターンにマッチする.
そこで,(2) は最も短い /usr/ に, (3) は最も長い /usr/local/bin/
にそれぞれマッチするためそれらが削除されて上の結果になる.
また,(4),(5) は同じパターンマッチを後ろから試みているが,
この aaa の値は / で終っていないのでマッチしない.
|