[bash][ワンライナー]抜け番のある連番ファイルをリネームする

[bash][ワンライナー]抜け番のある連番ファイルをリネームする

スクリーンショット画像などを整理する際、連番のファイル名を手動でリネームするのは骨が折れますよね?ダメ写真を削除したりして、抜け番が生じることもあるかと思います。しかし、bashのforループを使えばすんなりリネームすることができるので、是非試してみてください。まずはファイルの一覧を見てみましょう。

ご覧のように、ファイル名はすべて接頭語が「OS_INSTALL_」で、連番は4桁の数字になっています。

$ ls
OS_INSTALL_0001.jpg  OS_INSTALL_0019.jpg  OS_INSTALL_0039.jpg  OS_INSTALL_0058.jpg  OS_INSTALL_0078.jpg  OS_INSTALL_0096.jpg
OS_INSTALL_0002.jpg  OS_INSTALL_0020.jpg  OS_INSTALL_0040.jpg  OS_INSTALL_0059.jpg  OS_INSTALL_0079.jpg  OS_INSTALL_0097.jpg
OS_INSTALL_0003.jpg  OS_INSTALL_0021.jpg  OS_INSTALL_0041.jpg  OS_INSTALL_0060.jpg  OS_INSTALL_0080.jpg  OS_INSTALL_0098.jpg
OS_INSTALL_0004.jpg  OS_INSTALL_0022.jpg  OS_INSTALL_0042.jpg  OS_INSTALL_0061.jpg  OS_INSTALL_0081.jpg  OS_INSTALL_0099.jpg
OS_INSTALL_0005.jpg  OS_INSTALL_0024.jpg  OS_INSTALL_0043.jpg  OS_INSTALL_0062.jpg  OS_INSTALL_0082.jpg  OS_INSTALL_0100.jpg
OS_INSTALL_0006.jpg  OS_INSTALL_0025.jpg  OS_INSTALL_0044.jpg  OS_INSTALL_0064.jpg  OS_INSTALL_0083.jpg  OS_INSTALL_0101.jpg
OS_INSTALL_0007.jpg  OS_INSTALL_0026.jpg  OS_INSTALL_0045.jpg  OS_INSTALL_0065.jpg  OS_INSTALL_0084.jpg  OS_INSTALL_0102.jpg
OS_INSTALL_0008.jpg  OS_INSTALL_0027.jpg  OS_INSTALL_0046.jpg  OS_INSTALL_0066.jpg  OS_INSTALL_0085.jpg  OS_INSTALL_0103.jpg
OS_INSTALL_0009.jpg  OS_INSTALL_0028.jpg  OS_INSTALL_0047.jpg  OS_INSTALL_0067.jpg  OS_INSTALL_0086.jpg  OS_INSTALL_0104.jpg
OS_INSTALL_0010.jpg  OS_INSTALL_0030.jpg  OS_INSTALL_0049.jpg  OS_INSTALL_0068.jpg  OS_INSTALL_0087.jpg  OS_INSTALL_0105.jpg
OS_INSTALL_0011.jpg  OS_INSTALL_0031.jpg  OS_INSTALL_0050.jpg  OS_INSTALL_0070.jpg  OS_INSTALL_0088.jpg  OS_INSTALL_0106.jpg
OS_INSTALL_0012.jpg  OS_INSTALL_0032.jpg  OS_INSTALL_0051.jpg  OS_INSTALL_0071.jpg  OS_INSTALL_0089.jpg  OS_INSTALL_0107.jpg
OS_INSTALL_0013.jpg  OS_INSTALL_0033.jpg  OS_INSTALL_0052.jpg  OS_INSTALL_0072.jpg  OS_INSTALL_0090.jpg  OS_INSTALL_0108.jpg
OS_INSTALL_0014.jpg  OS_INSTALL_0034.jpg  OS_INSTALL_0053.jpg  OS_INSTALL_0073.jpg  OS_INSTALL_0091.jpg  OS_INSTALL_0109.jpg
OS_INSTALL_0015.jpg  OS_INSTALL_0035.jpg  OS_INSTALL_0054.jpg  OS_INSTALL_0074.jpg  OS_INSTALL_0092.jpg  OS_INSTALL_0111.jpg
OS_INSTALL_0016.jpg  OS_INSTALL_0036.jpg  OS_INSTALL_0055.jpg  OS_INSTALL_0075.jpg  OS_INSTALL_0093.jpg  OS_INSTALL_0112.jpg
OS_INSTALL_0017.jpg  OS_INSTALL_0037.jpg  OS_INSTALL_0056.jpg  OS_INSTALL_0076.jpg  OS_INSTALL_0094.jpg  OS_INSTALL_0113.jpg
OS_INSTALL_0018.jpg  OS_INSTALL_0038.jpg  OS_INSTALL_0057.jpg  OS_INSTALL_0077.jpg  OS_INSTALL_0095.jpg

数が多くてわかりにくいかと思いますので、抜け番があるあたりを見てみましょう。以下のように、23番目のファイルが抜けていることがわかります。

$ ls | egrep '(002[0-5])'
OS_INSTALL_0020.jpg
OS_INSTALL_0021.jpg
OS_INSTALL_0022.jpg
OS_INSTALL_0024.jpg
OS_INSTALL_0025.jpg

全体でどれだけ抜けがあるのかは ls コマンドをパイプで wc に渡してみるとわかります。

$ ls | tail -n 1 ; ls | wc -l
OS_INSTALL_0113.jpg
107

ご覧のように、連番のファイルが113まであるのに対してファイルの数は107です。

■ 桁数を無視してとりあえずはリネームする例 (あまり行儀がよろしくない)

ファイル名に抜け番があるということは、先ほどの例のように、ファイル名に含まれる番号の最大値よりも実際のファイル数のほうが少ないわけです。これを自動でリネームするということは、抜け番の次にある番号がその抜け番号を埋める、つまりファイル名がデクリメントされていくというわけです。まずはリネームの一部を見てみましょう。なお、このコマンドを実行した時点ではまだリネームされません。

$ for A in $(ls) ; do echo $A ; done | cat -n | awk '{print "mv",$2,"OS_INSTALL_"$1".jpg"}' | egrep '(002[0-5])'
mv OS_INSTALL_0020.jpg OS_INSTALL_20.jpg
mv OS_INSTALL_0021.jpg OS_INSTALL_21.jpg
mv OS_INSTALL_0022.jpg OS_INSTALL_22.jpg
mv OS_INSTALL_0024.jpg OS_INSTALL_23.jpg
mv OS_INSTALL_0025.jpg OS_INSTALL_24.jpg

桁数を無視してよいなら、awkの次のパイプに sh を渡してあげて実行しておしまいです。しかしこれでは折角元のファイルがゼロパディングでソートできているのに、台無しになってしまいます。

■ 桁数を揃えてリネームする例 (少しマシな実行例)

桁数を揃えたままリネームするなら、以下のようにするとよいでしょう。なお、今回の例でもコマンド実行時にはまだリネームされません。動作を確認するため、 mv コマンドの前に echo とタイプすることで「やっちまった!」を防いでいます。確認後OKなら echo を削るか、forループが終わったあと、つまり done の後にパイプで sh コマンドに渡してあげましょう。私はいつも done のあとに sh に渡しています。その方がOPミスで間違う可能性が低いからです。

$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo mv $FILES $(printf "OS-INSTALL_%04d.jpg\n" $num) ; num=$num+1 ; done | egrep '(002[0-5])'
mv OS_INSTALL_0020.jpg OS-INSTALL_0020.jpg
mv OS_INSTALL_0021.jpg OS-INSTALL_0021.jpg
mv OS_INSTALL_0022.jpg OS-INSTALL_0022.jpg
mv OS_INSTALL_0024.jpg OS-INSTALL_0023.jpg
mv OS_INSTALL_0025.jpg OS-INSTALL_0024.jpg
mv OS_INSTALL_0026.jpg OS-INSTALL_0025.jpg

上記の例のように、抜け番が埋められているのがおわかりいただけるかと思います。ただし、ちょっと工夫をしています。

最初に変数numを指定する前に、 declare コマンドで、「変数 num は数値型ですぜ」と宣言しています。これがあるおかげで、forループの最後に num 変数 に 1 を足して、ループが続く限りカウントアップされます。

続いて、ファイル名ですが、最初のアンダーバーをハイフンに置換しています。mvの前にif文でファイルの有無を見るほうが本当はよいのですが、まずはリネームできること優先でやっています。リネーム後のファイル名は printf で4桁の数字のファイル名を生成しています。

$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo mv $FILES $(printf "OS-INSTALL_%04d.jpg\n" $num) ; num=$num+1 ; done | sh
$ ls
OS-INSTALL_0001.jpg  OS-INSTALL_0019.jpg  OS-INSTALL_0037.jpg  OS-INSTALL_0055.jpg  OS-INSTALL_0073.jpg  OS-INSTALL_0091.jpg
OS-INSTALL_0002.jpg  OS-INSTALL_0020.jpg  OS-INSTALL_0038.jpg  OS-INSTALL_0056.jpg  OS-INSTALL_0074.jpg  OS-INSTALL_0092.jpg
OS-INSTALL_0003.jpg  OS-INSTALL_0021.jpg  OS-INSTALL_0039.jpg  OS-INSTALL_0057.jpg  OS-INSTALL_0075.jpg  OS-INSTALL_0093.jpg
OS-INSTALL_0004.jpg  OS-INSTALL_0022.jpg  OS-INSTALL_0040.jpg  OS-INSTALL_0058.jpg  OS-INSTALL_0076.jpg  OS-INSTALL_0094.jpg
OS-INSTALL_0005.jpg  OS-INSTALL_0023.jpg  OS-INSTALL_0041.jpg  OS-INSTALL_0059.jpg  OS-INSTALL_0077.jpg  OS-INSTALL_0095.jpg
OS-INSTALL_0006.jpg  OS-INSTALL_0024.jpg  OS-INSTALL_0042.jpg  OS-INSTALL_0060.jpg  OS-INSTALL_0078.jpg  OS-INSTALL_0096.jpg
OS-INSTALL_0007.jpg  OS-INSTALL_0025.jpg  OS-INSTALL_0043.jpg  OS-INSTALL_0061.jpg  OS-INSTALL_0079.jpg  OS-INSTALL_0097.jpg
OS-INSTALL_0008.jpg  OS-INSTALL_0026.jpg  OS-INSTALL_0044.jpg  OS-INSTALL_0062.jpg  OS-INSTALL_0080.jpg  OS-INSTALL_0098.jpg
OS-INSTALL_0009.jpg  OS-INSTALL_0027.jpg  OS-INSTALL_0045.jpg  OS-INSTALL_0063.jpg  OS-INSTALL_0081.jpg  OS-INSTALL_0099.jpg
OS-INSTALL_0010.jpg  OS-INSTALL_0028.jpg  OS-INSTALL_0046.jpg  OS-INSTALL_0064.jpg  OS-INSTALL_0082.jpg  OS-INSTALL_0100.jpg
OS-INSTALL_0011.jpg  OS-INSTALL_0029.jpg  OS-INSTALL_0047.jpg  OS-INSTALL_0065.jpg  OS-INSTALL_0083.jpg  OS-INSTALL_0101.jpg
OS-INSTALL_0012.jpg  OS-INSTALL_0030.jpg  OS-INSTALL_0048.jpg  OS-INSTALL_0066.jpg  OS-INSTALL_0084.jpg  OS-INSTALL_0102.jpg
OS-INSTALL_0013.jpg  OS-INSTALL_0031.jpg  OS-INSTALL_0049.jpg  OS-INSTALL_0067.jpg  OS-INSTALL_0085.jpg  OS-INSTALL_0103.jpg
OS-INSTALL_0014.jpg  OS-INSTALL_0032.jpg  OS-INSTALL_0050.jpg  OS-INSTALL_0068.jpg  OS-INSTALL_0086.jpg  OS-INSTALL_0104.jpg
OS-INSTALL_0015.jpg  OS-INSTALL_0033.jpg  OS-INSTALL_0051.jpg  OS-INSTALL_0069.jpg  OS-INSTALL_0087.jpg  OS-INSTALL_0105.jpg
OS-INSTALL_0016.jpg  OS-INSTALL_0034.jpg  OS-INSTALL_0052.jpg  OS-INSTALL_0070.jpg  OS-INSTALL_0088.jpg  OS-INSTALL_0106.jpg
OS-INSTALL_0017.jpg  OS-INSTALL_0035.jpg  OS-INSTALL_0053.jpg  OS-INSTALL_0071.jpg  OS-INSTALL_0089.jpg  OS-INSTALL_0107.jpg
OS-INSTALL_0018.jpg  OS-INSTALL_0036.jpg  OS-INSTALL_0054.jpg  OS-INSTALL_0072.jpg  OS-INSTALL_0090.jpg

■ 桁数を揃えてリネームする例 (正解例)

とりあえず先ほどの例ではリネームできましたが、ファイル名にハイフンが入ったままで気持ちが悪いです。またリネームしてあげてもよいのですが、実行するコマンドは少ないに越したことがありません。今度はtestコマンドをつけて、リネーム後のファイルがなければという条件式にマッチした時だけ、抜け番を埋めるようにします。勿論わざわざアンダーバーをハイフンにせず実行できます。というわけでまたまたechoで確認です。

$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo "[ ! -f $(printf "OS_INSTALL_%04d.jpg\n" $num) ] && mv $FILES $(printf "OS_INSTALL_%04d.jpg\n" $num)" ; num=$num+1 ; done | egrep '(002[0-5])'
[ ! -f OS_INSTALL_0020.jpg ] && mv OS_INSTALL_0020.jpg OS_INSTALL_0020.jpg
[ ! -f OS_INSTALL_0021.jpg ] && mv OS_INSTALL_0021.jpg OS_INSTALL_0021.jpg
[ ! -f OS_INSTALL_0022.jpg ] && mv OS_INSTALL_0022.jpg OS_INSTALL_0022.jpg
[ ! -f OS_INSTALL_0023.jpg ] && mv OS_INSTALL_0024.jpg OS_INSTALL_0023.jpg
[ ! -f OS_INSTALL_0024.jpg ] && mv OS_INSTALL_0025.jpg OS_INSTALL_0024.jpg
[ ! -f OS_INSTALL_0025.jpg ] && mv OS_INSTALL_0026.jpg OS_INSTALL_0025.jpg

コマンドの構文が期待どおりなので、実行してみましょう。なお、shコマンドには -x をつけると処理の中身を見ることができます。

$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo "[ ! -f $(printf "OS_INSTALL_%04d.jpg\n" $num) ] && mv $FILES $(printf "OS_INSTALL_%04d.jpg\n" $num)" ; num=$num+1 ; done | sh -x
+ '[' '!' -f OS_INSTALL_0001.jpg ']'
+ '[' '!' -f OS_INSTALL_0002.jpg ']'
+ '[' '!' -f OS_INSTALL_0003.jpg ']'
+ '[' '!' -f OS_INSTALL_0004.jpg ']'
+ '[' '!' -f OS_INSTALL_0005.jpg ']'
+ '[' '!' -f OS_INSTALL_0006.jpg ']'
+ '[' '!' -f OS_INSTALL_0007.jpg ']'
+ '[' '!' -f OS_INSTALL_0008.jpg ']'
+ '[' '!' -f OS_INSTALL_0009.jpg ']'
+ '[' '!' -f OS_INSTALL_0010.jpg ']'
+ '[' '!' -f OS_INSTALL_0011.jpg ']'
+ '[' '!' -f OS_INSTALL_0012.jpg ']'
+ '[' '!' -f OS_INSTALL_0013.jpg ']'
+ '[' '!' -f OS_INSTALL_0014.jpg ']'
+ '[' '!' -f OS_INSTALL_0015.jpg ']'
+ '[' '!' -f OS_INSTALL_0016.jpg ']'
+ '[' '!' -f OS_INSTALL_0017.jpg ']'
+ '[' '!' -f OS_INSTALL_0018.jpg ']'
+ '[' '!' -f OS_INSTALL_0019.jpg ']'
+ '[' '!' -f OS_INSTALL_0020.jpg ']'
+ '[' '!' -f OS_INSTALL_0021.jpg ']'
+ '[' '!' -f OS_INSTALL_0022.jpg ']'
+ '[' '!' -f OS_INSTALL_0023.jpg ']'
+ mv OS_INSTALL_0024.jpg OS_INSTALL_0023.jpg
+ '[' '!' -f OS_INSTALL_0024.jpg ']'
+ mv OS_INSTALL_0025.jpg OS_INSTALL_0024.jpg
+ '[' '!' -f OS_INSTALL_0025.jpg ']'
+ mv OS_INSTALL_0026.jpg OS_INSTALL_0025.jpg
+ '[' '!' -f OS_INSTALL_0026.jpg ']'
+ mv OS_INSTALL_0027.jpg OS_INSTALL_0026.jpg
+ '[' '!' -f OS_INSTALL_0027.jpg ']'
+ mv OS_INSTALL_0028.jpg OS_INSTALL_0027.jpg
+ '[' '!' -f OS_INSTALL_0028.jpg ']'
+ mv OS_INSTALL_0030.jpg OS_INSTALL_0028.jpg
+ '[' '!' -f OS_INSTALL_0029.jpg ']'
+ mv OS_INSTALL_0031.jpg OS_INSTALL_0029.jpg
+ '[' '!' -f OS_INSTALL_0030.jpg ']'
+ mv OS_INSTALL_0032.jpg OS_INSTALL_0030.jpg
+ '[' '!' -f OS_INSTALL_0031.jpg ']'
+ mv OS_INSTALL_0033.jpg OS_INSTALL_0031.jpg
+ '[' '!' -f OS_INSTALL_0032.jpg ']'
+ mv OS_INSTALL_0034.jpg OS_INSTALL_0032.jpg
+ '[' '!' -f OS_INSTALL_0033.jpg ']'
+ mv OS_INSTALL_0035.jpg OS_INSTALL_0033.jpg
+ '[' '!' -f OS_INSTALL_0034.jpg ']'
+ mv OS_INSTALL_0036.jpg OS_INSTALL_0034.jpg
+ '[' '!' -f OS_INSTALL_0035.jpg ']'
+ mv OS_INSTALL_0037.jpg OS_INSTALL_0035.jpg
+ '[' '!' -f OS_INSTALL_0036.jpg ']'
+ mv OS_INSTALL_0038.jpg OS_INSTALL_0036.jpg
+ '[' '!' -f OS_INSTALL_0037.jpg ']'
+ mv OS_INSTALL_0039.jpg OS_INSTALL_0037.jpg
+ '[' '!' -f OS_INSTALL_0038.jpg ']'
+ mv OS_INSTALL_0040.jpg OS_INSTALL_0038.jpg
+ '[' '!' -f OS_INSTALL_0039.jpg ']'
+ mv OS_INSTALL_0041.jpg OS_INSTALL_0039.jpg
+ '[' '!' -f OS_INSTALL_0040.jpg ']'
+ mv OS_INSTALL_0042.jpg OS_INSTALL_0040.jpg
+ '[' '!' -f OS_INSTALL_0041.jpg ']'
+ mv OS_INSTALL_0043.jpg OS_INSTALL_0041.jpg
+ '[' '!' -f OS_INSTALL_0042.jpg ']'
+ mv OS_INSTALL_0044.jpg OS_INSTALL_0042.jpg
+ '[' '!' -f OS_INSTALL_0043.jpg ']'
+ mv OS_INSTALL_0045.jpg OS_INSTALL_0043.jpg
+ '[' '!' -f OS_INSTALL_0044.jpg ']'
+ mv OS_INSTALL_0046.jpg OS_INSTALL_0044.jpg
+ '[' '!' -f OS_INSTALL_0045.jpg ']'
+ mv OS_INSTALL_0047.jpg OS_INSTALL_0045.jpg
+ '[' '!' -f OS_INSTALL_0046.jpg ']'
+ mv OS_INSTALL_0049.jpg OS_INSTALL_0046.jpg
+ '[' '!' -f OS_INSTALL_0047.jpg ']'
+ mv OS_INSTALL_0050.jpg OS_INSTALL_0047.jpg
+ '[' '!' -f OS_INSTALL_0048.jpg ']'
+ mv OS_INSTALL_0051.jpg OS_INSTALL_0048.jpg
+ '[' '!' -f OS_INSTALL_0049.jpg ']'
+ mv OS_INSTALL_0052.jpg OS_INSTALL_0049.jpg
+ '[' '!' -f OS_INSTALL_0050.jpg ']'
+ mv OS_INSTALL_0053.jpg OS_INSTALL_0050.jpg
+ '[' '!' -f OS_INSTALL_0051.jpg ']'
+ mv OS_INSTALL_0054.jpg OS_INSTALL_0051.jpg
+ '[' '!' -f OS_INSTALL_0052.jpg ']'
+ mv OS_INSTALL_0055.jpg OS_INSTALL_0052.jpg
+ '[' '!' -f OS_INSTALL_0053.jpg ']'
+ mv OS_INSTALL_0056.jpg OS_INSTALL_0053.jpg
+ '[' '!' -f OS_INSTALL_0054.jpg ']'
+ mv OS_INSTALL_0057.jpg OS_INSTALL_0054.jpg
+ '[' '!' -f OS_INSTALL_0055.jpg ']'
+ mv OS_INSTALL_0058.jpg OS_INSTALL_0055.jpg
+ '[' '!' -f OS_INSTALL_0056.jpg ']'
+ mv OS_INSTALL_0059.jpg OS_INSTALL_0056.jpg
+ '[' '!' -f OS_INSTALL_0057.jpg ']'
+ mv OS_INSTALL_0060.jpg OS_INSTALL_0057.jpg
+ '[' '!' -f OS_INSTALL_0058.jpg ']'
+ mv OS_INSTALL_0061.jpg OS_INSTALL_0058.jpg
+ '[' '!' -f OS_INSTALL_0059.jpg ']'
+ mv OS_INSTALL_0062.jpg OS_INSTALL_0059.jpg
+ '[' '!' -f OS_INSTALL_0060.jpg ']'
+ mv OS_INSTALL_0064.jpg OS_INSTALL_0060.jpg
+ '[' '!' -f OS_INSTALL_0061.jpg ']'
+ mv OS_INSTALL_0065.jpg OS_INSTALL_0061.jpg
+ '[' '!' -f OS_INSTALL_0062.jpg ']'
+ mv OS_INSTALL_0066.jpg OS_INSTALL_0062.jpg
+ '[' '!' -f OS_INSTALL_0063.jpg ']'
+ mv OS_INSTALL_0067.jpg OS_INSTALL_0063.jpg
+ '[' '!' -f OS_INSTALL_0064.jpg ']'
+ mv OS_INSTALL_0068.jpg OS_INSTALL_0064.jpg
+ '[' '!' -f OS_INSTALL_0065.jpg ']'
+ mv OS_INSTALL_0070.jpg OS_INSTALL_0065.jpg
+ '[' '!' -f OS_INSTALL_0066.jpg ']'
+ mv OS_INSTALL_0071.jpg OS_INSTALL_0066.jpg
+ '[' '!' -f OS_INSTALL_0067.jpg ']'
+ mv OS_INSTALL_0072.jpg OS_INSTALL_0067.jpg
+ '[' '!' -f OS_INSTALL_0068.jpg ']'
+ mv OS_INSTALL_0073.jpg OS_INSTALL_0068.jpg
+ '[' '!' -f OS_INSTALL_0069.jpg ']'
+ mv OS_INSTALL_0074.jpg OS_INSTALL_0069.jpg
+ '[' '!' -f OS_INSTALL_0070.jpg ']'
+ mv OS_INSTALL_0075.jpg OS_INSTALL_0070.jpg
+ '[' '!' -f OS_INSTALL_0071.jpg ']'
+ mv OS_INSTALL_0076.jpg OS_INSTALL_0071.jpg
+ '[' '!' -f OS_INSTALL_0072.jpg ']'
+ mv OS_INSTALL_0077.jpg OS_INSTALL_0072.jpg
+ '[' '!' -f OS_INSTALL_0073.jpg ']'
+ mv OS_INSTALL_0078.jpg OS_INSTALL_0073.jpg
+ '[' '!' -f OS_INSTALL_0074.jpg ']'
+ mv OS_INSTALL_0079.jpg OS_INSTALL_0074.jpg
+ '[' '!' -f OS_INSTALL_0075.jpg ']'
+ mv OS_INSTALL_0080.jpg OS_INSTALL_0075.jpg
+ '[' '!' -f OS_INSTALL_0076.jpg ']'
+ mv OS_INSTALL_0081.jpg OS_INSTALL_0076.jpg
+ '[' '!' -f OS_INSTALL_0077.jpg ']'
+ mv OS_INSTALL_0082.jpg OS_INSTALL_0077.jpg
+ '[' '!' -f OS_INSTALL_0078.jpg ']'
+ mv OS_INSTALL_0083.jpg OS_INSTALL_0078.jpg
+ '[' '!' -f OS_INSTALL_0079.jpg ']'
+ mv OS_INSTALL_0084.jpg OS_INSTALL_0079.jpg
+ '[' '!' -f OS_INSTALL_0080.jpg ']'
+ mv OS_INSTALL_0085.jpg OS_INSTALL_0080.jpg
+ '[' '!' -f OS_INSTALL_0081.jpg ']'
+ mv OS_INSTALL_0086.jpg OS_INSTALL_0081.jpg
+ '[' '!' -f OS_INSTALL_0082.jpg ']'
+ mv OS_INSTALL_0087.jpg OS_INSTALL_0082.jpg
+ '[' '!' -f OS_INSTALL_0083.jpg ']'
+ mv OS_INSTALL_0088.jpg OS_INSTALL_0083.jpg
+ '[' '!' -f OS_INSTALL_0084.jpg ']'
+ mv OS_INSTALL_0089.jpg OS_INSTALL_0084.jpg
+ '[' '!' -f OS_INSTALL_0085.jpg ']'
+ mv OS_INSTALL_0090.jpg OS_INSTALL_0085.jpg
+ '[' '!' -f OS_INSTALL_0086.jpg ']'
+ mv OS_INSTALL_0091.jpg OS_INSTALL_0086.jpg
+ '[' '!' -f OS_INSTALL_0087.jpg ']'
+ mv OS_INSTALL_0092.jpg OS_INSTALL_0087.jpg
+ '[' '!' -f OS_INSTALL_0088.jpg ']'
+ mv OS_INSTALL_0093.jpg OS_INSTALL_0088.jpg
+ '[' '!' -f OS_INSTALL_0089.jpg ']'
+ mv OS_INSTALL_0094.jpg OS_INSTALL_0089.jpg
+ '[' '!' -f OS_INSTALL_0090.jpg ']'
+ mv OS_INSTALL_0095.jpg OS_INSTALL_0090.jpg
+ '[' '!' -f OS_INSTALL_0091.jpg ']'
+ mv OS_INSTALL_0096.jpg OS_INSTALL_0091.jpg
+ '[' '!' -f OS_INSTALL_0092.jpg ']'
+ mv OS_INSTALL_0097.jpg OS_INSTALL_0092.jpg
+ '[' '!' -f OS_INSTALL_0093.jpg ']'
+ mv OS_INSTALL_0098.jpg OS_INSTALL_0093.jpg
+ '[' '!' -f OS_INSTALL_0094.jpg ']'
+ mv OS_INSTALL_0099.jpg OS_INSTALL_0094.jpg
+ '[' '!' -f OS_INSTALL_0095.jpg ']'
+ mv OS_INSTALL_0100.jpg OS_INSTALL_0095.jpg
+ '[' '!' -f OS_INSTALL_0096.jpg ']'
+ mv OS_INSTALL_0101.jpg OS_INSTALL_0096.jpg
+ '[' '!' -f OS_INSTALL_0097.jpg ']'
+ mv OS_INSTALL_0102.jpg OS_INSTALL_0097.jpg
+ '[' '!' -f OS_INSTALL_0098.jpg ']'
+ mv OS_INSTALL_0103.jpg OS_INSTALL_0098.jpg
+ '[' '!' -f OS_INSTALL_0099.jpg ']'
+ mv OS_INSTALL_0104.jpg OS_INSTALL_0099.jpg
+ '[' '!' -f OS_INSTALL_0100.jpg ']'
+ mv OS_INSTALL_0105.jpg OS_INSTALL_0100.jpg
+ '[' '!' -f OS_INSTALL_0101.jpg ']'
+ mv OS_INSTALL_0106.jpg OS_INSTALL_0101.jpg
+ '[' '!' -f OS_INSTALL_0102.jpg ']'
+ mv OS_INSTALL_0107.jpg OS_INSTALL_0102.jpg
+ '[' '!' -f OS_INSTALL_0103.jpg ']'
+ mv OS_INSTALL_0108.jpg OS_INSTALL_0103.jpg
+ '[' '!' -f OS_INSTALL_0104.jpg ']'
+ mv OS_INSTALL_0109.jpg OS_INSTALL_0104.jpg
+ '[' '!' -f OS_INSTALL_0105.jpg ']'
+ mv OS_INSTALL_0111.jpg OS_INSTALL_0105.jpg
+ '[' '!' -f OS_INSTALL_0106.jpg ']'
+ mv OS_INSTALL_0112.jpg OS_INSTALL_0106.jpg
+ '[' '!' -f OS_INSTALL_0107.jpg ']'
+ mv OS_INSTALL_0113.jpg OS_INSTALL_0107.jpg

ご覧のように、22番目のファイルまでは何もしていません。23番目のファイルが抜け番なので、24番目のファイルを23番にリネームしています。このように1つでも抜け番があれば、どんどんファイル名の数字を詰めていくので、以降のファイルはすべてリネームしています。また、2番目の抜け番もこのようによろしくやってくれています。

+ mv OS_INSTALL_0027.jpg OS_INSTALL_0026.jpg
+ '[' '!' -f OS_INSTALL_0027.jpg ']'
+ mv OS_INSTALL_0028.jpg OS_INSTALL_0027.jpg
+ '[' '!' -f OS_INSTALL_0028.jpg ']'
+ mv OS_INSTALL_0030.jpg OS_INSTALL_0028.jpg
+ '[' '!' -f OS_INSTALL_0029.jpg ']'
+ mv OS_INSTALL_0031.jpg OS_INSTALL_0029.jpg

リネーム前のファイル名は、そもそも存在しないファイル名が変数に入りません。また、リネーム後のファイル名は、forループで前回実行した回のリネーム後のファイル名に1を足しているので、上書きの心配もありません。

それではなぜtestコマンドで条件式をつけているのでしょう。その理由ですが、mvコマンドでエラーを出さないためです。testコマンドなしで実行したときはこうなります。

$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo "mv $FILES $(printf "OS_INSTALL_%04d.jpg\n" $num)" ; num=$num+1 ; done | sh -x
+ mv OS_INSTALL_0001.jpg OS_INSTALL_0001.jpg
mv: `OS_INSTALL_0001.jpg' と `OS_INSTALL_0001.jpg' は同じファイルです
+ mv OS_INSTALL_0002.jpg OS_INSTALL_0002.jpg
mv: `OS_INSTALL_0002.jpg' と `OS_INSTALL_0002.jpg' は同じファイルです
+ mv OS_INSTALL_0003.jpg OS_INSTALL_0003.jpg
mv: `OS_INSTALL_0003.jpg' と `OS_INSTALL_0003.jpg' は同じファイルです
+ mv OS_INSTALL_0004.jpg OS_INSTALL_0004.jpg
mv: `OS_INSTALL_0004.jpg' と `OS_INSTALL_0004.jpg' は同じファイルです
+ mv OS_INSTALL_0005.jpg OS_INSTALL_0005.jpg
mv: `OS_INSTALL_0005.jpg' と `OS_INSTALL_0005.jpg' は同じファイルです
(以下略)

エラーで止めずにすすめたいという乱暴な考えなら一応動きますが、エラーで止める処理がある場合はこうなります。

$ declare -i num ; num=1 ; for FILES in $(ls) ; do echo "mv $FILES $(printf "OS_INSTALL_%04d.jpg\n" $num)" ; num=$num+1 ; done | sh -uex
+ mv OS_INSTALL_0001.jpg OS_INSTALL_0001.jpg
mv: `OS_INSTALL_0001.jpg' と `OS_INSTALL_0001.jpg' は同じファイルです

ご覧のように、mvコマンドのエラーで処理が止まりました。なので、testコマンドの条件式が有用だということがおわかりいただけたかと思います。わざわざshに渡すときにエラーチェックしなくてもいいじゃんと言われればそれまでですが、仮にシェルスクリプトに書く場合、後続の処理を力技ですすめるの怖くないですか?なので、ここまですれば「一応動く」ではなく、「mvコマンドが出すエラーもちゃんとケアして」リネームできたと言えることになります。それではよい画像収集ライフを!

[amazonjs asin=”B00XKU53U4″ locale=”JP” title=”シェルプログラミング実用テクニック (Kindle版)”]

[amazonjs asin=”4774173444″ locale=”JP” title=”シェルプログラミング実用テクニック (Software Design plus)”]