複数のファイル名を一括変換する(bash初心者のあがき)

複数のファイル名を一括変換する(bash初心者のあがき)こんにちは。

この記事は試行錯誤の過程です。何かあれば、コメントで色々教えて下さい><。どんな小さなことでもよいです。

iOS向けのアプリを作っていく中でたくさんの画像ファイルを扱ったりすることもたまにあるんですね。その際に、いろいろ面倒な事が起こります。複数画像のリサイズはプレビューとか既存のアプリで出来るのですが、リネームに毎回つまづいていました。そこまで多くないものは一つ一つ変えたりして、、、

そこでちょっとこの問題を解消すべく、調べてみました。もちろん同じ事ができるアプリもあるでしょうけど、手元でちゃちゃっとやるために今回はbashを探ります。

ざっと検索したところ、【 複数のファイルの拡張子を一括変更する 】という記事がわかり易かったです。そのまま実行すれば動きます。

でも、%って何!#って何!!

という状態で応用ができなそうなので、この記述を元に色々調べてみました。

ベースとした記述1

for nm in *.txt; do
mv $nm ${nm%.txt}.doc;
done

まずはこれをベースとして考えます。

やってることはシンプルそうですが、意味がわかりません。とりあえず、最初のnm in *.txtでファイル名の最後が.txtになっているファイル名を取り出すということのようです。;はforの定義?の終わりでしょうかこれを除くとループしません。doからdoneまでがnmの個数分ループしているようです。

mvはファイルの移動ですがリネームにも使います。これは普段しようするのでOK。${}.docは変数ということですが、見慣れない表現です。ちょっと調べました。

まず、$は変数ということを表しています。1行目でnmにファイル名の配列を入れているので、$nmでファイル名を一つ一つ取り出していることになります。

これは${nm}と書いても同じようです。こういうのはよく見かけます。

%って何!

ここで、${nm%.txt}という部分が気になります。%って何!!調べてもすぐに出て来ません。。。色々動かして見たところ、変数の値が.txtで終わる場合、.txtをのぞいた値を作成しているようです。

for fname in *.eco;
do mv $fname ${fname%.eco}.e;
done

これはecoという謎の拡張子のついたファイルを、eという謎の拡張子に変換しているのですが、動きます。

for fname in *.eco;
do mv $fname ${fname%.ec}.e;
done

ecoの部分をecにすると動きません。

for fname in *.eco;
do mv $fname ${fname%.e*}.e;
done

eの後にワイルドカードを置いた結果動きました。%はやっぱり変数の値の最後の文字列が同じだったら切り取る記号なのかな。

ベースとした記述2

for nm in temp*; do
mv $nm HOGE${nm#temp};
done

はい同じように問題になるのが#です。#ってなにヾ(`Д´)ノ”

ですが、先ほど%に予想をつけたので同じように考えると変数の値の頭に同様の文字が会った場合切り取るということのようです。そこで頭にtempとつけたファイルをいくつか作って、記述通りやってみました。

出来ました(・∀・)

応用でfor!

forの記述をもう少し使えるようになりたかったので調べてみました。テストの用のファイルを一つ一つtouchやechoeで作るのが面倒だったので、同時進行でやってました。

参考にしたのはこちら: for文

そして、書いたのがこれ。

for n in $(seq 1 5); do 
touch ${n}.txt; 
done

数字名のファイルが5つできました!やった。man seqでみたところ、これは配列じゃないんですね。*seq 1 5**すると1から5までの数字が改行されて表示されました。

応用でファイル名の途中にある文字を変換する

さて、最終的にはこれがやりたかったのです!具体的にはabc@2x.pngをabc.pngに変えたいんですよー。逆もしかり。

テストのためにまず、テストしてるフォルダの中身を消して(rm *)、適当なファイル名を作成して(for name in a b c d e; do touch ${name}@2x.png; done ちなみに、半角スペースで区切ると一つ一つ取り出して変数に格納してくれるみたいです)、さてテスト始めます。

まずは、@2xを取り除くところです!

ぐは、これで出来るじゃん汗。

for fname in *; do 
mv $fname ${fname%'@2x.png'}.png; 
done

途中@2xを見つけ出してくれなかったので、”をつけました。@が良くなかったんでしょうね。

んー。逆に.pngを@2x.pngにするのも同様にできそう。。。

一応やりたいことは解決したのですが、せっかくなのでファイル名の真ん中にある文字を変えたい。

探したら出来ましたsedってコマンドを使うようですね。これ、正規表現というのでしょうか。奥が深そうですが、色々できそうですね。

for file in *@2x*; 
do mv $file `echo $file | sed 's/@2x//'`; 
done

その他参考

最後になりましたが、%についてこちらがわかり易かった(;;): Shell Script での文字列操作

追記です(2/8)

空白を含んだファイル名を扱うのに本当に苦労しました。2時間くらいかかったと思います。。。結果解消しました。

for fname in *" (mini)"*; do
mv "$fname" `echo $fname | sed 's/ (mini)//'`;
done

単純に””で囲めばいいんですね。こういうのってすぐ聞ける人が近くにいると効率がいいんだろうなぁ。。自力で悩んで獲得してもいいけど、それは複雑なことでこういう初歩的なことは早く解決するに越したことはないですからな。

Pocket
LINEで送る

You may also like...

  • Future

    複数のファイル名を一括変換する!

    すごいね!

    つきまして、複数のファイルをほかのファイル形式に変換したい場合、wondershareの「スーパーメディア変換!」に任せ!MACユーザー向け、とても使いやすいソフトです。http://www.wondershare.jp/mac/video-converter-ultimate.html