Loại bỏ đệ quy


140

Có ai có giải pháp để loại bỏ các tệp pesky ._ và .DS_Store mà người ta nhận được sau khi di chuyển các tệp từ máy Mac sang máy chủ Linux không?

Chỉ định một thư mục bắt đầu và để nó đi? thích / var / www / html / xuống ...


Mặc dù đây không phải là một IMO trùng lặp, bạn nên xem cái này: stackoverflow.com/questions/1280429/iêu
Grundlefleck

Mặc dù không phải những gì bạn đang yêu cầu. Tôi cho rằng đây là một giải pháp tốt hơn: unix.stackexchange.com/questions/9665/NH
Viktor

Câu trả lời:


169

thay đổi thư mục và sử dụng:

find . -name ".DS_Store" -print0 | xargs -0 rm -rf
find . -name "._*" -print0 | xargs -0 rm -rf

Không được thử nghiệm, hãy thử chúng mà không có xargs đầu tiên!

Bạn có thể thay thế khoảng thời gian sau khi tìm, bằng thư mục, thay vì thay đổi thư mục trước.

find /dir/here ...

2
Tôi biết câu hỏi của anh ấy đã không hỏi nó, nhưng tôi không bao giờ có thể nhớ: ví dụ của bạn có xử lý tên tệp có dấu cách không?
Grundlefleck

4
Vâng, đó là những gì print0 và -0 to xargs dành cho. Thông thường, nó sẽ không xử lý các khoảng trắng một cách chính xác, tuy nhiên với print0, nó sẽ in tên tệp có ký tự null ở cuối dòng, xarg với -0 sau đó sẽ sử dụng để chuyển toàn bộ đường dẫn tới xargs mà không có cơ hội có khoảng trắng được sử dụng tham số thứ hai hoặc thứ ba cho lệnh rm có thể rất tệ!
X-Istence

7
@X: findutils mới hơn hỗ trợ một -deletehành động, có thể rút ngắn điều này. @JT: Tìm kiếm này đệ quy theo .. Phụ thuộc vào có bao nhiêu tệp và thư mục con có ... bạn không thể chỉ cấm những tệp đó được tải lên?
ephemient

1
Không nên sử dụng -rcờ (đệ quy) trong trường hợp này vì bạn không muốn xóa bất kỳ thư mục nào ..
Daniel Zohar

2
@IlmariKaronen: điểm tốt. Sẽ không phải command rmlà một giải pháp tốt hơn (nghĩa là trực tiếp hơn)? (Bằng cách "trực tiếp" Tôi có nghĩa là nó giải quyết cụ thể vấn đề trong tay và không có gì khác, và do đó ít có khả năng có bất kỳ tác dụng phụ không mong muốn nào, và cũng sẽ tự giải thích nhiều hơn cho bất kỳ ai phải duy trì mã sau.)
iconoclast

93
find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete

86

Hỗ trợ findutils mới hơn -delete, vì vậy:

find . -name ".DS_Store" -delete

Thêm vào -printđể có được một danh sách xóa.

Lệnh sẽ hoạt động cho bạn nếu bạn có một hệ thống POSIX cập nhật, tôi tin. Ít nhất nó hoạt động với tôi trên OS X 10.8 và hoạt động cho những người khác đã thử nghiệm nó trên macOS 10.12 (Mojave).

Tín dụng cho @ephemient trong một bình luận trên bài đăng của @ X-Istence (nghĩ rằng nó đủ hữu ích để đảm bảo câu trả lời của chính nó).


1
Hoạt động trở lại trong OSX 10.6.
hoss

3
Giải pháp sạch nhất và đơn giản nhất, +1!
limist

6
@OneOfOne: như nhận xét của tôi nói, tôi đã nhận được điều này từ @ ephemient. Là người mới bắt đầu bash, tôi thấy giải pháp (có lẽ đúng hơn) của bạn ít có thể đọc và sử dụng được. Chúng có thể giống nhau về mặt chức năng nhưng tôi thấy cú pháp này cung cấp rõ ràng hơn.
rattray

1
Các '.' không cần thiết bởi vì findđệ quy vào thư mục làm việc hiện tại theo mặc định.
Tom Russell

Trong các phiên bản mới hơn của chương trình, thư mục có thể bị bỏ qua và nó sẽ ám chỉ thư mục làm việc hiện tại ( wikipedia ). Bạn vẫn cần .trên macOS 10.12 (Sierra).
Dem Pilafian

18

Lệnh đơn giản:

rm `find ./ -name '.DS_Store'` -rf
rm `find ./ -name '._'` -rf

Chúc may mắn!


1
Điều này làm việc tuyệt vời. NHƯNG một lời cảnh báo, tôi chỉ sử dụng rm -i tìm này ./ -name '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Cảm ơn chúa vì kịch bản dự phòng của tôi.
ryanjdillon

1
Nếu có quá nhiều tệp, lỗi này sẽ bị lỗi:-bash: /bin/rm: Argument list too long
Viktor

12
cd /var/www/html && find . -name '.DS_Store' -print0 | xargs -0 rm
cd /var/www/html && find . -name '._*' -print0 | xargs -0 rm

2
Tôi thích cái này tốt hơn đơn giản vì "rm" không có "-r" không cần thiết cho nhiệm vụ cụ thể này.
lotoffreetime

6

Bạn có thể chuyển sang zsh thay vì bash. Điều này cho phép bạn sử dụng ** để khớp các tệp ở bất kỳ đâu trong cây thư mục:

$ rm /var/www/html/**/_* /var/www/html/**/.DS_Store

Bạn cũng có thể kết hợp chúng như thế này:

$ rm /var/www/html/**/(_*|.DS_Store)

Zsh có rất nhiều tính năng khác mà bash thiếu, nhưng một mình nó đáng để thực hiện chuyển đổi. Nó có sẵn trong hầu hết (có thể là tất cả) các bản phân phối linux, cũng như cygwin và OS X.

Bạn có thể tìm thêm thông tin trên trang web zsh .


1
Một vấn đề có thể xảy ra: vì bạn không sử dụng xargs, bạn có thể gặp phải hạn chế độ dài đối số dòng lệnh. Ngoài ra, Bash 4 hỗ trợ **quá :-) (mặc dù không theo mặc định, shopt -s globstarcần phải được thiết lập)
ephemient

4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;

Sử dụng exec cho mỗi tập tin được tìm thấy là không nhanh chóng. Sẽ nhanh hơn khi tìm thấy in chúng ra và sau đó sử dụng xargs để gọi rm một lần.
X-Istence

3
Tuy nhiên, nếu bạn có một findcái hỗ trợ nó, +thì giống như xargs: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (cũng vậy, bạn đang thiếu một khoảng trống trước đó -exec)
Tạm dừng cho đến khi có thông báo mới.

3
chúng tôi không bao giờ có xargs trong ngày của tôi. Và chúng tôi phải đi bộ đến trường, lên dốc cả hai chiều .......
Martin Beckett

3

Ví dụ để xóa "Thumbs.db" một cách đệ quy;

find . -iname "Thumbs.db" -print0 | xargs -0 rm -rf

Xác thực bởi:

find . -iname "Thumbs.db"

Điều này bây giờ, không hiển thị bất kỳ mục nào với "Thumbs.db", bên trong đường dẫn hiện tại.


Hãy chắc chắn câu trả lời của bạn in ra một danh sách những gì đang bị xóa và giải thích lý do tại sao một người nào đó có thể muốn sử dụng xargsprint0thay vì exec(có lý do).
Josh Habdas


2

nếu bạn có Bash 4.0 ++

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done

2
Chạy một bản sao mới của rm cho mỗi tệp là lãng phí.
X-Istence

2
@ X-Istence tối ưu hóa sớm là lãng phí
Lucina

Nâng cao tính nguyên bản và sử dụng các đổi mới bash gần đây.
Josh Habdas

1

Một số điều cần lưu ý:

'-delete' không được đệ quy. Vì vậy, nếu .T tạmItems (thư mục) có tệp trong đó, lệnh sẽ thất bại.

Có rất nhiều tệp pesky được tạo bởi mac: .DS_Store ._. DS_Store .T tạm thời .ems .apdisk

Lệnh này giải quyết tất cả chúng. Lưu từ chạy tìm nhiều lần cho nhiều trận đấu.

find /home/foo \( -name '.DS_Store' -or -name '._.DS_Store' -or -name '._*' -or -name '.TemporaryItems' -or -name '.apdisk' \) -exec rm -rf {} \;

0

Điều này cũng hoạt động:

sudo rm -rf 2018-03-*

ở đây bạn xóa các tệp có tên của định dạng 2018-03- (một cái gì đó khác)

giữ cho nó đơn giản


Bạn không giải thích khi ai đó có thể muốn tiền tố một lệnh sudomà bạn cũng không cung cấp bất kỳ thông tin nào rmhoạt động trong bối cảnh câu trả lời của bạn.
Josh Habdas
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.