無限ループなしで親ディレクトリを子ディレクトリにコピーする

無限ループなしで親ディレクトリを子ディレクトリにコピーする

アプリケーション固有の理由から、親ディレクトリ全体をサブディレクトリにコピーする必要があります。例えば、

cp -r ../ tmp/

これの問題は、tmp/の内容を繰り返し再帰的にコピーしながら、無限ループに陥るということです。

この問題を解決するには、ディレクトリを圧縮してtmpに抽出するなど、いくつかありますが、特にエレガントな/ unixyソリューションがあるかどうか疑問に思います。

(注:私はApple OS / Xを使用しています。)

答え1

親ディレクトリから起動する場合は、findGNUを使用してこれを実行できますcp。現在存在するディレクトリ(インクルードディレクトリtmp)の名前が指定されており、folderそのディレクトリが空であると仮定tmpすると、次のことを実行できます。

cd ..
find . -path ./folder/tmp -prune -o -type f -exec cp --parents -t folder/tmp {} +

これはfindに以下のすべての項目.(前の項目..)をリストするように要求します。一致する場合を除き./folder/tmp、そうでない場合はファイルの場合はcpオプションに渡します(ソース階層を再構築するように指示します--parents)。cp

tmpまだコピーする必要があるファイルがすでに存在する場合、次のバリエーションはUnix-yが少し少なくなります。moreutils' sponge)しかし、以下をスキップしないでくださいtmp

cd ..
find . -type f -print0 | sponge | xargs -0 cp --parents -t folder/tmp

spongeコピーするファイルのリストを別の場所に保存すると、これを防ぐことができます(ただし、それを行うとあまりエレガントになります)。

cd ..
find . -type f -print0 > /tmp/filelist
xargs -0 cp --parents -t folder/tmp < /tmp/filelist
rm /tmp/filelist

cp以下を使用すると、GNUの要件を回避できますcpio

cd ..
find . -type f -print0 > /tmp/filelist
cpio -pmd0 folder/tmp < /tmp/filelist
rm /tmp/filelist

または

cd ..
find . -type f -print0 | sponge | cpio -pmd0 folder/tmp

空の場合は、tmp次の要件を回避することもできますmoreutils

cd ..
find . -path ./folder/tmp -prune -o -type f -print0 | cpio -pmd0 folder/tmp

答え2

対話型使用のためにmvの同様のケースを修正しました。

cd ..
mv * tmp

mv: cannot move ‘tmp’ to a subdirectory of itself, ‘tmp/tmp’

エラーを無視してください。他のすべてのアイテムは移動されました。 :-P。 cpと同じように機能せず、空のtmp / tmpを生成しますが、これはおそらく望むものではありません。

答え3

使用pax、コピー.subdir/tmpスキップsubdir/tmp

mkdir -p subdir/tmp &&
  pax -rws'|^\./subdir/tmp/.*||' . subdir/tmp

または、次のことができます。

mkdir -p subdir/tmp/subdir &&
  ln -s tmp subdir/tmp/subdir/tmp &&
  cp -a . subdir/tmp

subdir/tmp/subdir/tmpこれは自分自身を指すシンボリックリンクであり、cpその下には何も生成されません。必要に応じて、後で空のディレクトリに置き換えることができます。

関連情報