Làm thế nào để bạn di chuyển hàng loạt các tập tin lên một thư mục một cách an toàn?


10

Làm cách nào tôi có thể di chuyển các tệp lên một thư mục trong đó có thể có hàng trăm hoặc hàng nghìn tệp trong thư mục đó và bạn có thể không chắc chắn về việc có bị sao chép không ... Bạn sẽ sử dụng phương pháp nào?

Cách xử lý các bản sao sẽ khác nhau, đôi khi chúng ta sẽ ghi đè lên, đôi khi chúng ta cần an toàn hơn. IO có thể quan trọng vì đây là những máy chủ sản xuất. Nhưng số lượng đưa ra một lời nhắc cho các tệp không trùng lặp không phải là một tùy chọn. Việc bảo quản các quyền và dấu thời gian, v.v., rất quan trọng. Chúng ta thường sẽ không biết dữ liệu là gì.

Oh và nó sử dụng mvkhông bắt buộc rsync, cpgiải pháp hoan nghênh.

lưu ý: chúng tôi đang chạy CentOS 5.5 vì vậy hãy cho tôi biết nếu nó không hoạt động ở đó do đây là một tính năng mới hơn ...


Ypu muốn làm gì về bản sao?

@Iain phụ thuộc vào tình hình? Tôi làm việc tại một webhost ... nó thực sự phụ thuộc vào mvvà liệu chúng tôi có quan tâm đến việc bảo quản trong trường hợp ... và liệu chúng tôi đã thực hiện sao lưu chưa. Câu hỏi này khá mở. Tôi chỉ tìm kiếm các lựa chọn tốt, và có thể nhận xét về việc nó có thể cắn bạn hay không.
xenoterracide

Tôi giả sử có quá nhiều tập tin cho shell để xử lý mv * ../hay mv -i * ../?
Michael Mrozek

@Michael Tôi chắc chắn rằng nó thay đổi ... trong một số trường hợp có thể không. Trong một số trường hợp có thể. Tôi đang cố gắng nắm bắt càng nhiều lựa chọn cho công việc của mình càng tốt.
xenoterracide

Câu trả lời:


6

Tôi sẽ khuyên bạn nên sử dụng rsync từ cha mẹ:

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

sẽ sao lưu tất cả các tệp trùng lặp hiện có trong cha mẹ thành tệp gốc.


Tôi nghĩ -angụ ý-r
xenoterracide

@xenoterracide - Phải bạn 'r'
Tok

@Tok có thể làm bản sao như các liên kết cứng không? để không lãng phí IO. (như -lcho cp)
xenoterracide

@xenoterracide - Bạn có thể sử dụng -Hhoặc --hard-linkscờ cho rsync để bảo vệ các liên kết cứng.
Tok

1
@xenoterracide - Bạn có thể sử dụng --link-dest=DIRcờ để đạt được hành vi này như: rsync -avP --link-dest=/path/to/src /path/to/src/* /path/to/dest/nó sẽ liên kết cứng vào dst / bất kỳ tệp không thay đổi nào giữa src và src, trong trường hợp này là tất cả các tệp. Thông thường bạn thấy cờ này được sử dụng khi bạn muốn liên kết lại các tệp sao lưu mà không sao chép dữ liệu của chúng như --link-dest=/most/recent/backup.
Tok

4
cp -bal . ..

Điều này sẽ sao chép mọi thứ trong thư mục hiện tại vào thư mục phía trên nó, giữ lại tất cả các quyền, sử dụng các liên kết cứng để giảm thiểu IO nếu có thể và trên các bản sao nó tạo ra tên tệp ~

sau đó

rm -rf . ; cd .. ; rmdir <originaldir>;

có lẽ chạy vào số lượng lớn các vấn đề tập tin ... nhưng không phải là IO chuyên sâu như rsync.
xenoterracide

2

Trong ví dụ này sẽ di chuyển các tệp từ '/ Parent / old-dir' sang '/ Parent':

cd /parent

rsync -av --progress old-dir/ .

rm -rf old-dir

Theo quy tắc rsync, nó sẽ thay thế dups bằng các tệp mới hơn từ old-dir.


1

Bạn co thể thử

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

sẽ ghi đè lên các tập tin dupe trong ..

Bạn có thể sử dụng mv -u '{}' để không ghi đè nếu bản sao trong .. giống hoặc mới hơn


Tại sao đường ống tìm đến xargs? tại sao không sử dụng +
xenoterracide

1
@xenoterracide - Thói quen và tính di động (đó là phần mở rộng GNU). Trên hết, tôi vừa thử nó và không thể tìm ra cách truyền tham số thứ hai ..cho mv '{}' +lệnh khi + chỉ thêm vào cuối.

@ Tôi là + trong POSIX Tôi thực sự đã nói rằng GNU tìm thấy trước đó là muộn để có được nó.
xenoterracide

Bạn nói đúng nhưng tôi vẫn không thể tìm ra cách sử dụng ..

2
@xenoterracide: Với lõi core GNU : -exec mv -t .. -- {} +. Có thể : -exec sh -c 'mv -- "$@"' _ {} +.
Gilles 'SO- ngừng trở nên xấu xa'

1

mv -i chỉ nhắc nếu đích tồn tại.

yes n | mv -i …di chuyển tất cả các tệp không tồn tại trong thư mục đích. Trên FreeBSD và OSX, bạn có thể rút ngắn điều này thành mv -n ….

Lưu ý rằng cả hai sẽ không hợp nhất một đối số thư mục với một thư mục hiện có cùng tên trong thư mục đích.


Một vấn đề riêng là làm thế nào để hành động trên tất cả các tệp trong thư mục hiện tại. Có hai vấn đề: lấy tất cả các tệp ( *bỏ qua các tệp chấm) và không chạy vào một dòng lệnh. Trên Linux (hoặc nói chung hơn với GNU find và GNU coreutils):

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

Với GNU find nhưng không phải GNU coreutils (hoặc GNU coreutils):

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

Có thể:

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

Như thường lệ zsh làm cho mọi thứ dễ dàng hơn. Nó không có giới hạn độ dài dòng lệnh trong nội bộ, vì vậy nếu bạn sử dụng mvnội dung của nó, bạn không cần phải lo lắng về điều đó. Và bạn có thể yêu cầu nó không bỏ qua các tập tin dấu chấm với Dvòng loại toàn cầu. Giới hạn: điều này không hoạt động trên các hệ thống tập tin (kể từ zsh 4.3.10).

zmodload zsh/files
mv -i -- *(D) ..

nhiều tranh luận?
xenoterracide

0

Tôi đã nói trên ML của chúng tôi

mv * ..

rõ ràng điều này không an toàn lắm ... nó sẽ ghi đè lên mọi thứ. Nó có thể có những giới hạn mà tôi chưa bao giờ gặp phải.


2
Nếu bạn có số lượng tệp lớn, bạn có thể sẽ nhận được một 'danh sách đối số lỗi quá dài'.

2
Nó có thể làm những điều xấu nếu bạn có một tên tập tin bắt đầu bằng -. Nó sẽ không bắt các tập tin có tên bắt đầu bằng ..
Gilles 'SO- ngừng trở nên xấu xa'

0

Sau đây là một mẫu python mà tôi đã sử dụng để có hiệu quả tốt trong quá khứ.

#!/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")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.