Bagaimana Anda memindahkan file secara massal ke satu direktori dengan aman?

10

Bagaimana saya bisa memindahkan file ke direktori di mana mungkin ada ratusan atau ribuan file dalam direktori, dan Anda mungkin tidak yakin tentang apakah ada dupes di dalamnya ... Metode apa yang akan Anda gunakan?

Cara menangani dupes akan bervariasi, kadang-kadang kita akan menimpa, kadang-kadang kita harus lebih aman. IO dapat menjadi penting karena ini adalah server produksi. Tetapi jumlah yang diberikan prompt untuk file non duplikat bukan pilihan. Pelestarian izin, dan stempel waktu, dll, adalah penting. Kami biasanya tidak akan tahu apa datanya.

Oh dan menggunakan mvtidak diperlukan, rsync, cpsolusi menyambut.

Catatan: kami menjalankan CentOS 5.5 jadi beri tahu saya jika itu tidak akan berfungsi di sana karena itu fitur yang lebih baru ...

xenoterracide
sumber
Apa yang ingin Anda lakukan tentang dupes ypu?
@Sangat tergantung pada situasinya? Saya bekerja di hosting ... itu benar-benar tergantung pada mvdan apakah kita peduli tentang pelestarian dalam kasus ... dan apakah kita sudah membuat cadangan. Pertanyaan ini cukup terbuka. Saya hanya mencari pilihan yang baik, dan mungkin komentar tentang apakah itu bisa menggigit Anda dan bagaimana.
xenoterracide
Saya berasumsi ada terlalu banyak file untuk menangani shell mv * ../atau mv -i * ../?
Michael Mrozek
@ Michael, saya yakin itu bervariasi ... dalam beberapa kasus mungkin tidak. Dalam beberapa kasus mungkin. Saya mencoba untuk menangkap sebanyak mungkin opsi untuk pekerjaan saya dan mungkin.
xenoterracide

Jawaban:

6

Saya akan merekomendasikan menggunakan rsync dari induk:

rsync -avPr -b --suffix='-original' child/* .

yang akan mencadangkan semua file duplikat yang ada di induk ke file- asli.

Tok
sumber
Saya pikir -amenyiratkan-r
xenoterracide
@xenoterracide - Right you 'r'
Tok
@ Tok, mungkinkah melakukan salinan sebagai hardlink? agar tidak menyia-nyiakan IO. (suka -luntuk cp)
xenoterracide
@xenoterracide - Anda dapat menggunakan flag -Hatau --hard-linksuntuk rsync untuk mempertahankan tautan keras.
Tok
1
@xenoterracide - Anda dapat menggunakan --link-dest=DIRflag untuk mencapai perilaku ini sebagai: rsync -avP --link-dest=/path/to/src /path/to/src/* /path/to/dest/yang akan menghubungkan ke dst / file yang tidak berubah antara src dan src, dalam hal ini semua file. Biasanya Anda melihat bendera ini digunakan ketika Anda ingin menautkan kembali file cadangan tanpa menyalin data mereka seperti --link-dest=/most/recent/backup.
Tok
4
cp -bal . ..

Ini akan menyalin semua yang ada di direktori saat ini ke direktori di atasnya, mempertahankan semua izin, menggunakan hardlink untuk meminimalkan IO jika memungkinkan, dan pada duplikat itu menciptakan nama file ~

setelah itu

rm -rf . ; cd .. ; rmdir <originaldir>;
xenoterracide
sumber
mungkin mengalami sejumlah besar masalah file ... tetapi tidak IO intensif sebagai rsync.
xenoterracide
2

Dalam contoh ini akan memindahkan file dari '/ parent / old-dir' ke '/ parent':

cd /parent

rsync -av --progress old-dir/ .

rm -rf old-dir

Dengan aturan rsync, itu akan menggantikan dups dengan file yang lebih baru old-dir.

Alexander Pogrebnyak
sumber
1

Anda dapat mencoba

find . -maxdepth 1 -print0 | xargs -I '{}' -r0 mv '{}' ..

yang akan menimpa file dupe di ..

Anda dapat menggunakan mv -u '{}' untuk tidak menimpa jika dupe dalam .. adalah sama atau lebih baru


sumber
mengapa pipa ditemukan ke xargs? mengapa tidak menggunakan +
xenoterracide
1
@xenoterracide - Kebiasaan dan portabilitas (ini adalah ekstensi GNU). Selain itu, saya baru saja mencobanya dan tidak tahu cara meneruskan parameter kedua ..ke mv '{}' +perintah karena + hanya menambah akhir.
@Setelah + di POSIX saya benar-benar diberitahu sebelumnya menemukan GNU terlambat untuk mendapatkannya.
xenoterracide
Anda benar tetapi saya masih tidak dapat menemukan cara untuk menggunakan ..
2
@xenoterracide: Dengan coreutils GNU: -exec mv -t .. -- {} +. Portable: -exec sh -c 'mv -- "$@"' _ {} +.
Gilles 'SO- stop being evil'
1

mv -i hanya meminta jika tujuan ada.

yes n | mv -i …memindahkan semua file yang tidak ada di direktori tujuan. Pada FreeBSD dan OSX, Anda dapat mempersingkat ini menjadi mv -n ….

Perhatikan bahwa tak satu pun dari ini akan menggabungkan argumen direktori dengan direktori yang ada dengan nama yang sama di direktori tujuan.


Masalah terpisah adalah bagaimana bertindak pada semua file di direktori saat ini. Ada dua masalah: meraih semua file ( *menghilangkan file dot) dan tidak berjalan ke baris perintah. Di Linux (atau lebih umum dengan GNU find dan GNU coreutils):

find . -mindepth 1 -maxdepth 1 -exec mv -i -t .. -- {} +

Dengan GNU temukan tetapi bukan GNU coreutils (atau GNU coreutils yang lebih tua):

find . -mindepth 1 -maxdepth 1 -exec sh -c 'mv -i -- "$@" "$0"' .. {} +

Mudah dibawa:

find . -name . -o -exec sh -c 'mv -i -- "$@" "$0"' .. {} -type d -prune

Seperti biasa zsh membuat segalanya lebih mudah. Itu tidak memiliki batasan panjang baris perintah secara internal, jadi jika Anda menggunakan mvbuiltin Anda tidak perlu khawatir tentang itu. Dan Anda dapat mengatakan itu untuk tidak mengabaikan file dot dengan Dkualifikasi glob. Batasan: ini tidak berfungsi lintas sistem file (pada zsh 4.3.10).

zmodload zsh/files
mv -i -- *(D) ..
Gilles 'SANGAT berhenti menjadi jahat'
sumber
banyak argumen?
xenoterracide
0

Saya katakan di ML kami

mv * ..

jelas ini tidak terlalu aman ... itu akan menimpa banyak hal. Mungkin ada batas yang tidak pernah saya temui.

xenoterracide
sumber
2
Jika Anda memiliki banyak file, kemungkinan Anda akan mendapatkan 'daftar argumen kesalahan terlalu panjang'.
2
Mungkin melakukan hal-hal buruk jika Anda memiliki nama file yang dimulai dengan -. Itu tidak akan menangkap file yang namanya dimulai dengan ..
Gilles 'SO- stop being evil'
0

Berikut ini adalah templat python yang saya gunakan untuk efek yang baik di masa lalu.

#!/usr/bin/env python
#
# Bart Kastermans, www.bartk.nl
#
# rename of collection of files in a directory
import os
import shutil

# only work on files whose name starts with a D
files = [filename for filename in os.listdir ("/Users/kasterma/Music/Audio Hijack/") if filename[0] =="D"]

for filename in files:
    shutil.move (filename, filename [:23] + ".mp3")
kasterma
sumber