親ディレクトリに移動したいサブディレクトリに大量のファイルとディレクトリがあります。上書きする必要のあるファイルとディレクトリがすでにターゲットディレクトリにあります。ターゲットにのみ存在するファイルは変更しないでください。 mv
にそれを強制することはできますか?それ (mv * ..
)文句を言う
mv: cannot move `xyz' to `../xyz': Directory not empty
何が欠けていますか?
コマンドcp -r * ..
に続けてrm -rf *
を使用して、それらを宛先にコピーしてからソースを削除する必要があります。
mv
を使用してディレクトリを「マージ」できるとは思いません。
rsync
はおそらくここでより良いオプションです。 rsync -a subdir/ ./
と同じくらい簡単です。
filename
:contents
形式のテストツリー:
./file1:root
./file2:root
./dir/file3:dir
./dir/file4:dir
./subdir/dir/file3:subdir
./subdir/file1:subdir
実行中rsync
:
$ rsync -a -v subdir/ ./
sending incremental file list
./
file1
dir/
dir/file3
与える:
./file1:subdir
./file2:root
./dir/file3:subdir
./dir/file4:dir
./subdir/dir/file3:subdir
./subdir/file1:subdir
次に、mv
をエミュレートするには、おそらくソースディレクトリを削除する必要があります。
$ rm -r subdir/
与える:
./file1:subdir
./file2:parent
./dir/file3:subdir
./dir/file4:dir
これが間違っている場合、希望する結果を提供する同様の例(この回答の上部近くにある私のテストツリーを使用するなど)を提供できますか?
rsync
は、コピー後に--remove-source-files
パラメータを使用してソースを削除できます。これは、希望どおりの操作を行うための便利な方法です。
rsync man page
から:
--remove-source-files sender removes synchronized files (non-dir)
cp
とrm
を使用してこれを行うことができますが、(おそらく)転送を回避しようとしている大量のデータをコピーする必要はありません。 @mattdmは 彼のコメント でこれに言及しました、そして 別の質問に対する回答 はさまざまなオプションについてより完全な議論を持っています。
cp -rlf source destination
rm -r source
基本的に、cp
コマンドの-l
オプションは、データを新しいファイルにコピーするのではなく、ファイルへのハードリンクを作成します。
以下は、/path/to/source/root
の下から/path/to/destination/root
の下の対応するパスにファイルを移動するスクリプトです。
テストされていないコードに注意してください。
export dest='/path/to/destination/root'
cd /path/to/source/root
find . -type d \( -exec sh -c '[ -d "$dest/$0" ]' {} \; -o \
-exec sh -c 'mv "$0" "$dest/$0"' {} \; -Prune \) \
-o -exec sh -c '
if ! [ -e "$dest/$0" ]; then
mv -f "$0" "$dest/$0";
fi
' {} \;
このスレッドは何年にもわたって存在し、まだGoogleで1位にランクされているので、別のメソッドを追加したいと思いました。通常、これを行う方法:サブディレクトリのコンテンツをtarballにパックし、tarballを親ディレクトリに移動して、デフォルトの--overwrite動作で抽出します。これはまさにあなたが探していることを行います。その後、サブディレクトリを削除できます。
cd xyz
tar -cvzpf tmp.tar.gz *
mv tmp.tar.gz ../tmp.tar.gz
cd ..
tar -xvzpf tmp.tar.gz
rm -rf xyz
rm -f tmp.tar.gz
十分なストレージがある場合は、次の方法でそれを行うことができます。
mv -bfv directory_1/* directory_2/ # all duplicate source files/directories
# will have ~ appended to them
find -name "*~" -delete # will recursively find and delete all files
# with ~ on the end
末尾に〜が付いている重要なファイルがないことを確認してください。ただし、存在する場合は、デフォルトの代わりに--suffix=whateveryouwant
を追加できます。