renameコマンドが使えれば簡単にファイル名を一括変更できるのですが、macOSのように利用できない環境も多々あります。そのような環境でファイル名を一括変換する方法です。
1.find, sed, xargsで変更する方法
コマンドのテンプレートはこうなります。
1 | find <検索対象ディレクトリパス> -type f | sed 'p;s/<置換条件>/<置換文字列>/' | xargs -n2 mv |
まず、findコマンドで検索対象ディレクトリからファイルのみを検索します。実行結果はこうなります。
1 2 3 4 | find ./ -type f .//aaaa001.txt .//aaaa002.txt .//aaaa003.txt |
次にsedコマンドでfindコマンドの結果を検索置換します。これはfindコマンドで検索した結果の文字列を検索置換し、その結果を出力するだけで、実際にファイル名が変更される訳ではありません。実行結果はこうなります。
1 2 3 4 5 6 7 | find ./ -type f | sed 'p;s/aaaa/bbbb/' .//aaaa001.txt .//bbbb001.txt .//aaaa002.txt .//bbbb002.txt .//aaaa003.txt .//bbbb003.txt |
次にxargsコマンドで、それまでのコマンドの出力結果を引数として利用しmvコマンドを実行します。出力結果のうち2つずつをmvコマンドの引数として与える為(元のファイル名、変更後のファイル名)、-n2オプションを加えます。
実行結果はこうなります。
1 2 3 | find ./ -type f | sed 'p;s/aaaa/bbbb/' | xargs -n2 mv ls bbbb001.txt bbbb002.txt bbbb003.txt |
以上です。
2.for, find, mv, 変数展開で変更する方法
Facebookのお友達の桑畑さんにforと変数展開を用いた一括変更方法教えて頂いたので、調べて試してみました。桑畑さん、ありがとうございました^^
コマンドのテンプレートはこうなります。
1 | for <変数:列挙するファイル名> in `find <検索対象ディレクトリのパス> -type f`; do mv <変数:列挙するファイル名> ${<変数:列挙するファイル名><置換条件>/<置換文字列>}; done |
このうち、findに関する処理は1の場合と同様です。
forコマンドは、リストに対してループ処理を行います。今回はfindで検索した結果をリストとし、ループ処理を行い、ファイル名の変更処理を行います。
${<変数:列挙するファイル名><置換条件>/<置換文字列>}は、「変数展開」と呼ばれる処理のうちの1つで、文字の置換処理を行います。
実行結果はこうなります。
1 2 3 4 5 | ls aaaa-001.txt aaaa-002.txt aaaa-003.txt for filename in `find . -type f`; do mv $filename ${filename/aaaa/bbbb}; done ls bbbb-001.txt bbbb-002.txt bbbb-003.txt |
以上です。
宮崎県在住。
プログラムを書いて暮らしています。趣味はルアーフィッシング、ギター。