it-swarm-tr.com

Mv ile hedef dosyaların üzerine nasıl yazılır?

Ben üst dizine taşımak istediğiniz bir alt dizinde bir ton dosya ve dizin var. Hedef dizinde üzerine yazılması gereken bazı dosyalar ve dizinler zaten var. Yalnızca hedefte bulunan dosyalar el değmeden bırakılmalıdır. mv bunu yapmaya zorlayabilir miyim? O (mv * ..) şikayet ediyor

mv: cannot move `xyz' to `../xyz': Directory not empty

Neyi kaçırıyorum?

175
EricSchaefer

Bunları hedefe kopyalamanız ve ardından cp -r * .. Ve ardından rm -rf * Komutlarını kullanarak kaynağı silmeniz gerekir.

mv kullanarak dizinleri "birleştirebilirsiniz" sanmıyorum.

128
dogbane

rsync muhtemelen burada daha iyi bir seçenek olacaktır. rsync -a subdir/ ./.

Test ağacım filename: contents biçiminde:

./file1:root
./file2:root
./dir/file3:dir
./dir/file4:dir
./subdir/dir/file3:subdir
./subdir/file1:subdir

rsync çalıştırılıyor:

$ rsync -a -v subdir/ ./
sending incremental file list
./
file1
dir/
dir/file3

Verir:

./file1:subdir
./file2:root
./dir/file3:subdir
./dir/file4:dir
./subdir/dir/file3:subdir
./subdir/file1:subdir

Ve sonra, mv öykünmesi için, muhtemelen kaynak dizini kaldırmak istiyorsunuz:

$ rm -r subdir/

Giving:

./file1:subdir
./file2:parent
./dir/file3:subdir
./dir/file4:dir

Bu yanlışsa, lütfen istediğiniz sonucu veren benzer bir örnek verebilir misiniz (örneğin, bu cevabın üst kısmındaki test ağacımı kullanarak)?

77
Mikel

rsync, --remove-source-files parametresiyle kopyalandıktan sonra kaynağı silebilir. Bu, istediğinizi yapmak için uygun bir yol olmalıdır.

rsync man page 'Dan:

        --remove-source-files   sender removes synchronized files (non-dir)
52
Mike Chen

Bunu cp ve rm ile yapabilirsiniz, ancak büyük miktarda veriyi kopyalamaksızın (muhtemelen) aktarmayı engellemeye çalışıyorsunuzdur. @mattdm onun yorum ve başka bir soru için bir cevap 'da çeşitli seçenekler hakkında daha eksiksiz bir tartışma yaptı.

cp -rlf source destination
rm -r source

Esasen, cp komutu için -l Seçeneği, verilerini yeni dosyalara kopyalamak yerine dosyalara sabit bağlantılar oluşturur.

24
palswim

İşte dosyaları /path/to/source/root Altındaki /path/to/destination/root Altındaki ilgili yola taşıyan bir komut dosyası.

  • Hem kaynakta hem de hedefte bir dizin varsa, içerikler tekrar tekrar taşınır ve birleştirilir.
  • Kaynakta bir dosya veya dizin var, ancak hedefte yoksa, taşınır.
  • Hedefe zaten var olan herhangi bir dosya veya dizin geride bırakılır. (Özellikle birleştirilmiş dizinler kaynakta geride bırakılır. Bunu düzeltmek kolay değildir.)

Dikkat edin, denenmemiş kod.

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
' {} \;

Bu konu yıllarca orada ve hala başka bir yöntem eklemek istedim bu yüzden google # 1 sırada yer alıyor. Nasıl genellikle bunu yapmak: alt dizini bir tarball içine paketleme, tarball üst dizine kadar hareket ve sonra varsayılan - overwrite davranışı ile ayıklayın. Bu tam olarak aradığınızı yapar. Daha sonra alt dizinizi kaldırabilirsiniz.

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
3
Simon Kraus

Yeterli depolama alanınız varsa, bunu şu şekilde yapabilirsiniz:

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

Sonlarında ~ bulunan önemli bir dosya olmadığından emin olun, ancak varsa --suffix=whateveryouwant yerine varsayılan _.

0
4D3H2