macOSで大量のデータをコピーする

Finderを使って操作すると固まってしまってうまくいきませんでした。ターミナルを使った操作の備忘録です。

% echo /Volumes/from/folder/IMG_{123..456}.{JPG,CR2} | xargs -J{} -t -n1 -P4 cp -p {} /Volumes/to/folder

macOS Sonoma 14.3.1、zsh 5.9 (x86_64-apple-darwin23.0) で確認しています。

コピー元の指定

コピー元はデジタル一眼カメラで利用しているSDカードです。DCIMフォルダ配下にフォルダが1つあり、その中に連番のファイルが置かれている構成です。このとき、コピー元がフォルダ内のすべてのファイルであれば * で指定すればOKです。

今回はファイル番号の始点と終点を指定する方法としました。ここでzsh(man zshexpnに記載があります)のBrace Expansion(ブレース展開)構文を利用します。{123..456}は始点と終点の数値を指定しピリオド2つで連結します。こうすることで始点と終点を含む形で展開されます。この例では123から456までのファイルをコピー対象しています。以下サンプルになります。ゼロ始まりも、指定した通りに展開されます。

% echo {8..12}
8 9 10 11 12
% echo {08..12}
08 09 10 11 12

拡張子はカンマで文字を指定しています。これはそれぞれで展開されます。先ほどの指定では行っていませんが、拡張子JPGとJPEGのE有無もブレース展開で表現できます。

% echo {JP{,E}G,CR2}
JPG JPEG CR2

ここまでで複数のブレース展開を組み合わせました。それぞれすべての組み合わせで展開されます。

% echo {09..10}.{JP{,E}G,CR2}
09.JPG 09.JPEG 09.CR2 10.JPG 10.JPEG 10.CR2

コピー操作の表現

コピー元のファイルを指定できたので、コピー操作を実行します。そのままではcpコマンドを呼び出せないため、(コピー元の指定で使ったechoコマンドの結果である)標準入力をコマンド呼び出しに渡すためxargsコマンドを利用します。

-Jオプションは、のちに渡される呼び出しコマンドの置換場所を指定する文字列を指定します。ここは多くのケースで使われる{}を指定しています。

-tオプションは実行コマンドを標準出力に書き出します。cpコマンドは操作中に何も表示しないので、xargsコマンド側で実行しているコマンドを表示することで、進行具合を確認できるようにしています。

-nオプションは標準入力のパラメータのうち、指定した数を実行コマンドに渡します。1を指定することで1つずつcpコマンドに渡すようにしています。cpコマンドはファイルシステム操作のため、コマンド実行中の中断を避けたいです。そのため、1つずつ呼び出すことで停止機会を増やすようにしています。

% echo {01..10} | xargs -n1 echo
01
02
03
04
05
06
07
08
09
10
% echo {01..10} | xargs -n2 echo
01 02
03 04
05 06
07 08
09 10

続いて-Pオプションです。同時に起動するプロセス数を指定します。0を指定すると可能な限り同時にプロセスを立ち上げます。例示では4プロセス起動しており-nオプションと合わせて同時に4つのcpコマンドを起動することになります。

最後にcpコマンドの-pオプションです。コピー先のファイル作成日などをcpコマンド実行時点とせず、できる限りコピー元の属性値を複製するために指定しています。


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *