先日職場のMacを入れ替えまして、M1 Mac miniになったのですが、CPUが変わったのでTimemachineからの復帰ではなくデータフォルダーをコピーしてアプリケーションはすべて新規インストールしたのですが、細かなスクリプトをコピーし忘れたあげく、バックアップに置いていたデータも使えなくなってしまって(使っていたiMacのFusionドライブだったのですが、HDDを換装してデータディスクを取り出して保管していたつもりなのですが、片割れのSSDを初期化して読み込めなくなってしまいました)、なんとかスクリプトの復帰はできたのですが、今後のための覚書です。
※今回紹介するスクリプトを利用して不利益が生じたとしても自己責任でお願いします。
こちらでは一切のフォローは行えません。必ず失っても良いファイルで十分に検証してください。
※別パターンのスクリプト(選択したフォルダに親フォルダの名前を追記)はこちら
拡張子でフォルダ分け
1つのフォルダに入った複数のファイルをjpgやtifなど拡張子毎のフォルダに分けるスクリプトです。
Automatorで作成しサービスに登録することで、納品データの入ったフォルダを右クリックしサービスより選ぶ事で拡張子毎にフォルダを作成し、自動で整理してくれます。
- アプリケーションフォルダーより【Automator】を起動し、1.【新規書類】をクリックし、歯車の2.【クイックアクション】を選択して、3.【選択】をクリックします。
- ウィンドウ右上、ワークフローが受け取る現在の項目欄で4.【フォルダ】を選び、検索対象を5.【Finder】にします。
(これでFinderでフォルダを右クリック時にサービス欄にこのスクリプトが表示されます) - ウィンドウ左側、6.【ファイルとフォルダ】から7.【フォルダの内容を取得】をドラッグで右側グレー部分にドロップします。
- ウィンドウ左側、8.【ユーティリティ】から9.【シェルスクリプトを実行】をドラッグで右側グレー部分(フォルダの内容を取得の下)にドロップします。
- ドロップした【シェルスクリプトを実行】内の右上入力の引き渡し方法で10.【引数として】を選択します。
その下、11.【入力欄】の中身に次のスクリプトをコピペして入れ替えて、わかりやすい名前(例:拡張子でフォルダ分け)で保存すれば終了です。
for f in "$@"
do
fpath=${f%/*} #ファイルのパスを取得
ext=${f##*.} #ファイルの拡張子を取得
if [ ! -e $fpath/$ext -o ! -d $fpath/$ext ]; then
mkdir $fpath/$ext #拡張子でフォルダを作成
fi
mv $f $fpath/$ext #フォルダへ移動
done
シェルスクリプトの解説
間違ってたらごめんなさい大体あってるはず。
デスクトップにあるjpgの入った【フォルダA】を選択して右クリックでサービスの中にできた【拡張子でフォルダ分け】を選択した時の挙動を例に挙げます。
- for f in “$@”
引数として受け取ったファイル”$@”をfに代入し一つずつに処理する
この時点の【f】の中身はファイルのフルパスが入っています。
例:/Users/ユーザー名/Desktop/フォルダA/file.jpg - do
1行目forの範囲ここから - fpath=${f%/*} #ファイルのパスを取得
fpathに引数として受け取った【f】から後方一致でのマッチ部分削除(最短マッチ)で、最後の【/】とファイル名を削除したパスを取得
例:/Users/ユーザー名/Desktop/フォルダA - ext=${f##*.} #ファイルの拡張子を取得
extに引数として受け取った【f】から前方一致でのマッチ部分削除(最長マッチ)で、最後の【.】とそれ以前を削除したパスを代入
例:jpg - if [ ! -e $fpath/$ext -o ! -d $fpath/$ext ]; then
if文 指定のフォルダに拡張子の名前の付いたフォルダがあるか確認し、無ければ次の行へ - mkdir $fpath/$ext #拡張子でフォルダを作成
指定のフォルダへ取得した拡張子名のフォルダを作成 - fi
if文ここまで - mv $f $fpath/$ext #フォルダへ移動
作成(もしくは存在)した拡張子名のフォルダへファイルを移動 - done
1行目forの範囲ここまで
スクリプトを実行すると、下記のファイルが拡張子名のフォルダに入るので、一つのフォルダにjpgやtifが複数入っていても自動で整理してくれます。
【/Users/ユーザー名/Desktop/フォルダA/file.jpg】
↓
【/Users/ユーザー名/Desktop/フォルダA/jpg/file.jpg】
このようになります。
パスの取得は下記のマッチを使用、上記スクリプトでは変数名は$f、パターンはディレクトリの【/】や拡張子手前の【.】と【*】で文字列を使用
${変数名#パターン} 前方一致でのマッチ部分削除(最短マッチ)
${変数名##パターン} 前方一致でのマッチ部分削除(最長マッチ)
${変数名%パターン} 後方一致でのマッチ部分削除(最短マッチ)
${変数名%%パターン} 後方一致でのマッチ部分削除(最長マッチ)
機種名でフォルダ分け
こちらも使用方法は同じですが、ファイル名の命名ルールを利用しファイル名の 【_】 より手前を製品名としてフォルダで分けています。
例:【EOS-R5_正面.tif】の場合EOS-R5フォルダを作成し【EOS-R5/EOS-R5_正面.tif】このようにフォルダに入れてくれます。
フォルダ名にしたい名前が先頭では無い、もしくは【_】で分けられていない場合はスクリプトを修正してみてください。
違うのはスクリプトだけなので画像は省きます。
- アプリケーションフォルダーより【Automator】を起動し、歯車の【クイックアクション】を選択します。
- ウィンドウ右上、ワークフローが受け取る現在の項目欄で【フォルダ】を選び、検索対象を【Finder】にします。
(これでFinderでフォルダを右クリック時にサービス欄にこのスクリプトが表示されます) - ウィンドウ左側、ファイルとフォルダから【フォルダの内容を取得】をドラッグで右側グレー部分にドロップします。
- ウィンドウ左側、ユーティリティから【シェルスクリプトを実行】をドラッグで右側グレー部分(フォルダの内容を取得の下)にドロップします。
- ドロップした【シェルスクリプトを実行】内の右上入力の引き渡し方法で【引数として】を選択します。
その下、入力欄の中身に次のスクリプトをコピペして入れ替えて、わかりやすい名前(例:機種名でフォルダ分け)で保存すれば終了です。
for f in "$@"
do
fpath=${f%/*} #ファイルのパスを取得
fname=${f##*/} #ファイル名を取得
model=${fname%%_*} #ファイル名から"_"より手前の文字列を取得
if [ ! -e $fpath/$model -o ! -d $fpath/$model ]; then
mkdir $fpath/$model #機種名でフォルダを作成
fi
mv $f $fpath/$model #フォルダへ移動
done
シェルスクリプトの解説
こちらも間違ってたらごめんなさい大体あってるはず。
デスクトップにあるjpgの入った【フォルダB】を選択して右クリックでサービスの中にできた【機種名でフォルダ分け】を選択した時の挙動を例に挙げます。
- for f in “$@”
引数として受け取ったファイル”$@”をfに代入し一つずつに処理する
この時点の【f】の中身はファイルのフルパスが入っています。
例:/Users/ユーザー名/Desktop/フォルダB/EOS-R5_正面.tif - do
1行目forの範囲ここから - fpath=${f%/*} #ファイルのパスを取得
fpathに引数として受け取った【f】から後方一致でのマッチ部分削除(最短マッチ)で、最後の【/】とファイル名を削除したパスを代入
例:/Users/ユーザー名/Desktop/フォルダB - fname=${f##*/} #ファイル名を取得
fnameに引数として受け取った【f】から前方一致でのマッチ部分削除(最長マッチ)で、最後の【/】以降のファイル名を代入
例:EOS-R5_正面.tif - model=${fname%%_*} #ファイル名から”_”より手前の文字列を取得
modelに先ほど取得したファイル名の後方一致でのマッチ部分削除(最長マッチ)で、_より後ろを削除したファイル名を代入
例:EOS-R5 - if [ ! -e $fpath/$model -o ! -d $fpath/$model ]; then
if文 指定のフォルダにmodelに代入した名前の付いたフォルダがあるか確認し、無ければ次の行へ - mkdir $fpath/$model #機種名でフォルダを作成
指定のフォルダへ取得した機種名のフォルダを作成 - fi
if文ここまで - mv $f $fpath/$model #フォルダへ移動
作成(もしくは存在)した機種名のフォルダへファイルを移動 - done
1行目forの範囲ここまで
スクリプトを実行すると、下記のファイルが拡張子名のフォルダに入るので、
【/Users/ユーザー名/Desktop/フォルダB/EOS-R5_正面.tif】
↓
【/Users/ユーザー名/Desktop/フォルダB/EOS-R5/EOS-R5_正面.tif】
このようになります。
中にファイルが100入っていようが、選択するだけで自動的に整理してくれます。
スクリプトが必要になったわけ
クライアントへのデータ納品時に「ファイルを製品ごとに分けて納品してね」と言われてしまい、ファイル名で順番に並んでるからわかるでしょと思いつつも、製品ごとにフォルダを作り、手作業で入れていたのですが、データに修正が入るたびにフォルダ分けをやり直したりしていると、いつか間違ってしまうので自動で振り分けられるようなスクリプトを探したんですが、良いものが見つからず自分で作ってみることになりました。
MacはAutomatorがあるのでこういった処理の自動化が出来て良いですね。
思ってもスクリプトがわからなくてなかなか作ることが出来ないんで大変ですが、思い通りに動くと楽しいですよね。