Sao chép tất cả các tệp và thư mục không bao gồm các tệp và thư mục lật đổ trên OS X


14

Tôi đang cố gắng sao chép tất cả các tệp và thư mục từ thư mục này sang thư mục khác, nhưng loại trừ một số tệp nhất định. Cụ thể, tôi muốn loại trừ các tập tin và thư mục subversion. Tuy nhiên, tôi muốn một giải pháp chung chung nhưng súc tích.

Tôi tưởng tượng tôi sẽ thấy cần phải loại trừ một số loại tệp trong tương lai gần. Ví dụ: tôi có thể muốn loại trừ .svn, * .bak và * .prj.

Đây là những gì tôi đã kết hợp với nhau, nhưng nó không hiệu quả với tôi. Phần đầu tiên, tìm tác phẩm, nhưng tôi đang làm gì đó sai với xargscp . Tôi đã thử cp có và không có -R. Ngoài ra, tôi đang sử dụng OS X và nó dường như có phiên bản xargs ít tính năng hơn các hệ thống linux.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory

Tôi có thể sai, nhưng tôi nghĩ rằng điều này là khó khăn hơn bạn nghĩ. Ngay cả khi findlệnh của bạn sử dụng đúng cách -pruneđể loại trừ các mục .svn, thì bạn sẽ chuyển -Rcờ cpcho lệnh đó được đệ quy. Khi làm như vậy, bạn sẽ mất bất kỳ mức độ chi tiết nào bạn có trong findlệnh. Tôi sẽ sửa lại điều này trong một phút, nhưng tôi nghĩ câu trả lời là không sử dụng -Rtrong cplệnh.
Telemachus

Nó dường như hoạt động với tôi trên một hệ thống Linux. Bạn có thể nói cụ thể hơn về việc "nó không hoạt động" nghĩa là gì không? Bất kỳ thông báo lỗi? Tập tin nhận / không nhận được sao chép mà bạn mong đợi?
Tạm dừng cho đến khi có thông báo mới.

Đó là -Rcờ, tôi khá chắc chắn. Xóa cái đó đi và bạn sẽ ổn thôi (mặc dù bạn có thể muốn thêm -mindepth 1vào để bỏ qua thư mục thư mục toplevel mà bạn không muốn sao chép, tôi giả sử)
Telemachus

Tôi thường làm những điều này bằng cách sao chép mọi thứ, và sau đó xóa các tệp không mong muốn trong các thư mục đích. Điều đó thường đơn giản hơn nhiều.
Jan Doggen

Câu trả lời:


22

(Đã chỉnh sửa sau khi đọc lại câu hỏi. Người hỏi cho biết rsync chưa được cài đặt)

Một vấn đề có thể xảy ra với giải pháp find / xargs của bạn là khoảng trắng trong tên tệp. Để giải quyết vấn đề đó, hãy báo cho find và xargs sử dụng ký tự null (ASCII 0) để tách các tệp đã tìm thấy:

find ./sourcedirectory -not ( -name .svn -a -prune ) -print0 | xargs -0 -IFILES cp FILES ./destinationdirectory

Nếu bạn thấy rằng rsync có sẵn, tôi vẫn nghĩ rằng rsync là giải pháp tốt hơn nhiều:

Sử dụng rsync với tùy chọn -C. Từ trang người đàn ông rsync :

Đây là một tốc ký hữu ích để loại trừ một loạt các tệp mà bạn thường không muốn chuyển giữa các hệ thống. Nó sử dụng một thuật toán tương tự như CVS để xác định xem có nên bỏ qua một tập tin hay không.

Điều này sẽ cho rsync bỏ qua các mẫu này:

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state .nse_depinfo *~
#* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj 
*.so *.exe *.Z *.elc *.ln core .svn/ .git/ .bzr/

Ví dụ:

rsync -avC /path/to/source/directory /path/to/destination/directory

. Tìm kiếm 'dấu gạch chéo')


Oh chuột, tôi vừa đọc lại câu hỏi của bạn và thấy rằng bạn nói rằng bạn chưa cài đặt rsync. Trên MacBook Pro của tôi (OS X 10.6.1), nó có trong / usr / bin / rsync. Nó cũng được cài đặt cho tôi theo Tiger (10,4) và Leopard (10,5).
Doug Harris

Tôi khá chắc chắn rằng bạn (và OP) không muốn -Rcờ trong xargsphần lệnh.
Telemachus

Bắt tốt, tôi đã sao chép nó từ câu hỏi ban đầu. Sẽ chỉnh sửa ngay.
Doug Harris

1
Cảm ơn Doug! Một điều tôi giảng, "sử dụng công cụ phù hợp cho công việc". Gần đây tôi đã đến từ thế giới Windows đến OSX và vẫn đang loay hoay trong sự thiếu hiểu biết. Tôi đã đăng câu hỏi tương tự này trong một kênh linux và ai đó đã nhanh chóng nói, chỉ cần sử dụng "rsynch" Tôi đã gõ "rsynch" trong thiết bị đầu cuối và thấy nó không tồn tại và tiếp tục điều tra tìm kiếm | phương pháp xargs. Tôi hơi bướng bỉnh như thế. Dù sao đi nữa, OSX có "rsync" theo mặc định và bài đăng của bạn rất hữu ích. Tôi chưa có đủ kinh nghiệm ở đây để biết cái nào tốt hơn, nhưng rsync chắc chắn ngắn gọn hơn nhiều. Cảm ơn!
Michael Prescott

Nếu bạn sẽ thực hiện bất kỳ công việc nào với các máy linux ngoài công việc của bạn trên OS X, tôi nghĩ bạn sẽ thấy đáng để bạn dành thời gian tìm hiểu cách sử dụng rsync. Chức năng chính của nó là sao chép thông minh chỉ những thứ đã thay đổi (như bản sao trên cửa sổ, nếu bạn quen với điều đó). Bởi vì nó chỉ sao chép delta, đó là một cách tuyệt vời để xử lý các bản sao lưu (không phải cỗ máy thời gian), triển khai mã và những thứ tương tự.
Doug Harris

2

Không phải là giải pháp chung nhưng ... bạn có thể sử dụng lệnh xuất svn để tạo bản sao của không gian làm việc mà không cần các thư mục siêu dữ liệu .svn.


Không gây khó chịu, nhưng tôi không chắc tại sao câu trả lời này lại được bình chọn. Tôi biết về khả năng của svn, nhưng "Tôi muốn một giải pháp chung chung nhưng ngắn gọn. Tôi tưởng tượng rằng tôi sẽ thấy cần phải loại trừ một số loại tệp trong tương lai gần"
Michael Prescott

2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

nếu bạn muốn, bạn thậm chí có thể đặt 'pv' hoặc một cái gì đó tương tự ở giữa 2 quy trình tar.


2

Một cách bẩn thỉu nhưng nhanh chóng và súc tích:

cp -r source destination
find destination -iname .svn |xargs rm -rf

Điều này sao chép một thư mục sang thư mục khác (do đó tùy chọn đệ quy -r) và sau đó xóa đệ quy bất cứ thứ gì có tên .svn(bỏ qua trường hợp).


1

Tôi sẽ đi về nó theo một cách khác, sử dụng tar và cơ chế loại trừ của nó.

Từ trong thư mục đích:

tar -X excludefile -C source -f - . | tar xf -

Điều này sẽ cd vào nguồn, ghi lại nội dung, ngoại trừ những gì được liệt kê trong loại trừ, và sau đó gỡ bỏ nó vào thư mục hiện tại.


Giải pháp thanh lịch thực sự.
Nick Stinemates

tốt, đó là cùng một câu trả lời tôi đã đưa ra, chỉ sau đó. cộng với bạn phải ở trong thư mục đích ... :)
akira

0

Câu trả lời được chỉnh sửa : Vấn đề là -Rlàm cho bản sao của bạn được đệ quy và do đó cuối cùng bạn sẽ sao chép các tệp bị ẩn. Đây là những gì tôi sẽ sử dụng:

find source/  -mindepth 1 -not \( -name .svn -prune \) | xargs -Iitem cp item target/

Các -mindepth 1lá cờ nói findđể bỏ qua thư mục cấp đầu. Vì bạn muốn sao chép tất cả nội dung của thư mục đó vào một thư mục toplevel mới, tôi giả sử bạn không muốn điều đó.

Như Chris Nava đã nói trong câu trả lời của mình , đã có một cách tích hợp để làm điều này nếu chúng ta đang nói về các thư mục SVN, nhưng vì bạn đã yêu cầu một giải pháp tổng quát hơn, điều này có thể giúp ích một chút.


Cảm ơn Telemachus, nó rất hữu ích. Tôi không có kinh nghiệm để phê bình, nhưng tôi sẽ nhắc lại những gì tôi đã kể từ bài viết gốc của mình. "Xargs bị hỏng" Nhà bình luận irc vô danh nói với tôi rằng đã truyền cảm hứng cho tôi để nhìn xung quanh nhiều hơn một chút và tôi nghĩ câu trả lời của Doug Harris đã giải quyết vấn đề. Điều đó nói với xargs sử dụng các ký tự null. Tôi nghĩ đó là công tắc -0?
Michael Prescott

@Michael: xargskhông bị hỏng, nhưng trên các hệ thống giống Unix, mặc định là không sử dụng tên tệp (hoặc tên thư mục) có khoảng trắng trong đó. Nếu bạn có khoảng trắng hoặc ký tự "hài hước" trong tên tệp (hoặc tên thư mục), thì bạn phải làm thêm để giải quyết vấn đề đó. (Trong GNU find, có toàn bộ phần trong mantrang có tên "PHIM TUYỆT VỜI" vì vấn đề này.) -0Cờ trong xargs-print0để được findtrợ giúp xử lý các vấn đề này. Tôi hứa với bạn, tuy nhiên, bạn không muốn sử dụng -Rtrong lệnh sao chép của mình. Nó sẽ hoàn tác bất cứ điều gì bạn làm để tránh các thư mục SVN.
Telemachus

0

Tôi cho rằng nó phụ thuộc vào cây của bạn lớn như thế nào, nhưng tại sao không chỉ sao chép mọi thứ trước, sau đó cắt các thư mục .svn sau:

find /dest-dir -type d -name .svn -exec rm -rf {} \;

?


Không có bất kỳ điểm chuẩn nào, suy nghĩ ban đầu của tôi là đây là một sự lãng phí gấp đôi các chu kỳ CPU: sao chép và loại bỏ. Có thể mất thêm một chút thời gian của con người để tạo ra findlệnh đúng , nhưng bạn chỉ làm điều đó một lần. Bạn có thể sử dụng lệnh hàng trăm lần, khi bạn hiểu đúng.
Telemachus

@Telemachus - đúng, nhưng đó là những gì máy tính (được cho là) ​​giỏi - làm những thứ khó khăn để chúng ta không phải làm! Thực sự - có hại gì khi sao chép một số tệp chỉ để xóa chúng ngay sau đó, nếu điều đó có nghĩa là các lệnh bạn phát minh ra để làm điều đó rất đơn giản?
Steve Folly

@Steve: thực sự không có hại. Theo như nó đi, đây là một giải pháp tốt. Nó tuân theo một nguyên tắc tôi thích: "Làm điều đơn giản nhất có thể có hiệu quả." Mặt khác, nó vi phạm một nguyên tắc khác mà tôi thích hơn nữa: "Tìm hiểu các công cụ của bạn." Tôi thích học cách sử dụng findbản thân tốt hơn, để tôi không phải làm điều này. Nhưng bạn đã đúng: không có gì thực sự sai với giải pháp này.
Telemachus

@Telemachus: Tôi đồng ý với "Tìm hiểu công cụ của bạn". Khi tôi bắt đầu, tôi chắc chắn rằng lệnh tìm kiếm của tôi ở trên sẽ trông rất khó hiểu đối với tôi sau đó :-)
Steve Folly


0

Bạn cũng có thể làm ngược lại. Sao chép mọi thứ sau đó xóa các thư mục .svn bằng lệnh dưới đây:

find . | grep ".svn" | xargs rm -rf
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.