Linuxで、findで見つけたファイルをディレクトリ構造をたもったままコピー、移動させる方法4個
Pocket

Twitter見てた時、そういう処理の仕方についてわからないというのを見かけたので、一応何かの時のために残しておくことにする。
通常、LinuxやMacに入ってるmvやcpでは、コピー先のディレクトリが無かったら作成するような機能はないので、ひと手間必要になる。

1.findからxargsを使ってコピー、移動させる場合

findからxargsに対象のファイルPATHを渡して、それをcp、mvを使ってコピーや移動をさせる場合。
この場合、コピー時にディレクトリが無いとエラーになってしまうので、一度mkdirで(フォルダがない場合に)生成させる必要がある。
以下、サンプルコード(mvの場合は、cpのとこを書き換え)。

cd /path/from; find ./ -type f ... | xargs -I@ bash -c 'DIR=/path/to/dir;mkdir -p $DIR/$(dirname @);cp @ $DIR/@'

 

ちゃんとシェルスクリプトとかで書いて対応するなら、forやwhileを使ってやるといいだろう(xargsだと都度プロセス立ち上げるから遅いし)。

find ./ -type f ... | while read -r var;
do
  dir=/tmp/test_3;
  mkdir -p $dir/$(dirname $var);
  cp $var $dir/$var;
done

2.findからrsyncを利用してコピーさせる場合

findの結果に対し、ディレクトリの同期等を行うツールであるrsyncを使って、ディレクトリ構造とセットでコピーすることもできる。
以下、サンプルコード。

rsync -R $(find ./ -type f ...) /path/to/dir

 

mvと同等の処理(コピー後にオリジナルを削除する)場合は、「–remove-source-files」オプションを付与する。

rsync --remove-source-files -R $(find ./ -type f ...) /path/to/dir

 

パイプから渡す場合、コマンド置換してるところをcatにしとけばいいだろう。

Sponsored Links

3.findからcpの代わりにinstallコマンドを指定する

Makefileなどでよく利用されるinstallコマンドでは、コピー時にPATHがないとディレクトリを自動で作成するオプション(-D)が用意されている。
このため、cpの代わりにxargsから渡してやると、比較的カンタンにディレクトリ構造ごとコピーができる。

find ./ --type ... | xargs -I@ install -D @ /path/to/dir/@

 

元ファイルの削除をする機能はないので、必要であれば別途findからrmに渡してやるといいだろう。

4.findからtarによるアーカイブ化→展開を利用する場合

tarはディレクトリ構造を保持するので、それを利用する場合。
以下のように、標準入出力でtarのアーカイブ→展開をしてやればいい。

tar cf - $(find ./ -type f -name ...) | tar xf - -C /path/to/dir

 

こちらも、元ファイルの削除が必要な場合は別途対応が必要。

 

Pocket

Written by blacknon

インフラエンジニア(…のつもり)。 仕事で使うならクライアントはWindowsよりはUNIXの方が好き。 大体いつも眠い。

Leave a Comment

メールアドレスが公開されることはありません。

*