シェルスクリプトで複数ファイルを一括リネームする方法
シェルスクリプトを使って複数ファイルを一括リネームする方法を解説します.
例えば, ディレクトリにapple1, apple2, apple3, apple4, apple5というファイルがあり, これをorange1, orange2, orange3, orange4, orange5というファイル名に変えたいときには, 次のようにします.
$ ls
apple1 apple2 apple3 apple4 apple5
$ for f in apple* ; do ; mv $f ${f/apple/orange} ; done
$ ls
orange1 orange2 orange3 orange4 orange5
さて, ここでリネームを実際に行っているのは, 3行目になります. 1行になっていますが, これを複数行になおしてみると, 次のようになります.
for f in apple*
do
mv $f ${f/apple/orange}
done
apple*の部分は, この作業ディレクトリにおいて, apple1 apple2 apple3 apple4 apple5と同様の意味をもちます. つまり, apple1~apple5のそれぞれが変数fに入れられて, for文が回っていきます.
3行目では, リネームをするために, mvが呼ばれ, また, 変数fに対して文字列置換が行われています. 例えば, fにapple3が入っている時には, 3行目は,
mv apple3 orange3
のようになります. これが全てのapple1~apple5ファイルに適応されるため, ファイルは一括リネームされます.
文字列置換に関しては, よろしければ「シェルスクリプト入門」を参考になさって下さい.
さて, この一貫の処理をスクリプトにしますと, 以下のようになります.
#!/bin/bash
if [ $# -lt 3 ]
then
echo "変更前の文字列, 変更後の文字列, 変更したいファイル名を入力して下さい."
exit 1
fi
args=$*
extra_args="$1 $2"
files=${args#$extra_args}
for f in $files
do
mv $f ${f/$1/$2}
done
[訂正] 文字列置換は, /bin/shでは行えなかったかもしれません. 上記コード内で一行目を#!/bin/shとしていたため, 訂正致します. 正しくは, 一行目を#!/bin/bashとしてください.
まず, 3行目から7行目までは, エラー処理です. 引数が3つより少ないとエラー文を吐いて終了します.
9行目から11行目で, 全ての引数から, "変更前の文字列", と"変更後の文字列"を抜き取っています. 少し詳しく言いますと, 9行目で変数argsに全ての引数を代入しています. 10行目で1つ目と2つ目の引数に空白を挟んだ文字列を作ってextra_argsという変数に代入, 11行目でfilesという変数に変数argsから変数extra_argsの文字列を削除したものを代入しています. 以上の操作で, 3つ目以降の引数, つまり変更したいファイル名を全てfilesという変数に入れることが出来ました.
13行目から, 16行目は上で解説した通りです. では, 使ってみます.
$ ls
file1 file2 file3 file4 file5 rename.sh
$ ./rename.sh file doc file*
$ ls
doc1 doc2 doc3 doc4 doc5 rename.sh
使うときには, 実行権を付けることを忘れないようにしましょう.