目的
ある特定の拡張子をもつファイルを一括でリネームしたい。
特にファイル名に「(」や「 」や「-」が入っているものを扱うときにエスケープせずに行いたい
ShellScript
ディレクトリ以下にあるファイル一覧をfind -name
で抽出してそれをパイプしてreadで出力をfile読ませてwhileで終わるまでループさせる
リネーム処理の際は、ファイルパスからファイル名とディレクトリ名を分離してファイル名のみ変更する
ディレクトリ名を抽出するにはパターンマッチを用いて、「/」より後ろの部分を削除する{f%/*}
を用いる。ファイル名はbasename
を使って抽出してみた。
find ~/Documents/target -name "*.foo" | while read file
do
echo ${file}
dir_name="${file%/*}"
file_name=$(basename ${file})
echo ${dir_name}
echo ${file_name}
done
その他のパターンマッチ
https://qiita.com/mriho/items/b30b3a33e8d2e25e94a8
さんを参照しました。
スクリプト | 動作 |
---|---|
${変数名#パターン} | 前方一致での削除(パターンにマッチした最初より前の部分を削除する) |
${変数名##パターン} | 前方一致での削除(パターンにマッチした最後より前の部分を削除する) |
${変数名%パターン} | 後方一致での削除(パターンにマッチした最初より後ろの部分を削除する) |
${変数名%%パターン} | 後方一致での削除(パターンにマッチした最後より後ろの部分を削除する) |
${変数名/置換前文字列/置換後文字列} | 文字列置換(最初に一致したもののみ) |
${変数名//置換前文字列/置換後文字列} | 文字列置換(一致したものすべて) |
Python
globを用いてファイルのリストを取得してリネームする
Python3.5以降
import os
import glob
list=glob.glob("/User/myname/Documents/target/**.foo", recursive=True)
for path in list
before_name=os.path.basename(path)
dir_name=os.path.dirname(path)
after_name=before_name.replace(" ",r"¥ ")
os.rename("{0}/{1}".format(dir_name,before_name),"{0}/{1}".format(dir_name,after_name))
subprocessを使ってリネームする方法もあるがShellScriptをpython内に記述することになるので割愛する