Xóa các tập tin và thư mục bằng tên của họ. Không có tập tin hoặc thư mục


32

Tôi cần xóa tất cả dữ liệu đã biên dịch:

  • thư mục được gọi là build,
  • thư mục được gọi là obj,
  • * .so tập tin.

Tôi đã viết một lệnh

find \( -name build -o -name obj -o -name *.so \) -exec rm -rf {} \;

đi qua tất cả các thư mục đệ quy và xóa tất cả những gì tôi cần.

Tại sao tôi có một đầu ra như vậy vào cuối? Có lẽ tôi nên viết một lệnh khác.

find: `./3/obj': No such file or directory
find: `./3/build': No such file or directory
find: `./1/obj': No such file or directory
find: `./1/build': No such file or directory
find: `./2/obj': No such file or directory
find: `./2/build': No such file or directory

bạn đang ở hệ thống nào? bạn nên luôn luôn sử dụng findnhư thế này mà find /search_directory optionsbỏ qua thư mục tìm kiếm không phải là một ý tưởng hay
Kiwy

Tự động xóa như thế này là một ý tưởng tồi. Bạn có thể có một kịch bản cung cấp cho bạn các ứng cử viên, sau đó bạn nên xem lại để đảm bảo rằng bạn không xóa bất cứ điều gì quan trọng hoặc cần thiết cho hệ thống. Bạn không rõ ràng nơi bạn đang chạy này. Nếu bạn chỉ làm điều này trong một không gian người dùng, tôi cho rằng nó không thể gây hại nhiều, nhưng bạn nên chắc chắn rằng bạn không vô tình làm điều này trong một khu vực hệ thống. Bạn chắc chắn muốn chạy một kịch bản như người dùng.
Faheem Mitha

@ Kiwy, @ FaheemMitha, lệnh sẽ chỉ được sử dụng trong chỉ thị dự án; Nó sẽ không làm hại gì ở đó.
Maksim Dmitriev

Câu trả lời:


54

Sử dụng -prunetrên các thư mục mà bạn sẽ xóa bằng mọi cách để nói rằng findđừng bận tâm tìm các tệp trong đó:

find . \( -name build -o -name obj -o -name '*.so' \) -prune -exec rm -rf {} +

Cũng lưu ý rằng *.socần phải được trích dẫn nếu không nó có thể được mở rộng bởi shell vào danh sách các .sotệp trong thư mục hiện tại.

Tương đương với GNU -regex-type của bạn sẽ là:

find . \( -name build -o -name obj -o -name '*?.so' \) -prune -exec rm -rf {} +

Lưu ý rằng nếu bạn sẽ sử dụng cú pháp cụ thể của GNU, bạn cũng có thể sử dụng -deletethay vì -exec rm -rf {} +. Với -delete, GNU findbật -depthtự động. Nó không chạy các lệnh bên ngoài theo cách đó, nó hiệu quả hơn và cũng an toàn hơn vì nó loại bỏ điều kiện cuộc đua trong đó ai đó có thể khiến bạn xóa các tệp sai bằng cách thay đổi thư mục thành liên kết tượng trưng trong khoảng thời gian đó findtìm một tập tin và rmloại bỏ nó (xem info -f find -n 'Security Considerations for find'để biết chi tiết).

find . -regextype posix-egrep -regex '.*/((obj|build)(/.*)?|.+\.so)' -delete

-deletecũng xử lý những thứ như không gian tốt hơn
Izkata

@Izkata, không tốt hơn -exec rm -rf {} +cái nào cũng không có vấn đề với những cái đó.
Stéphane Chazelas

@StephaneChazelas - Tôi bối rối về {}- họ có nên được trích dẫn hay không? Nó dường như hoạt động mà không có dấu ngoặc kép, nhưng ví dụ GNU Findutils Manual sử dụng '{}'. Ông có thể làm rõ?
grebneke

1
@grebneke, tôi nghĩ rằng có một bài đăng ở đâu đó có thể cần trích dẫn trong các phiên bản rất cũ csh, nhưng tôi không bao giờ có thể xác minh khiếu nại đó. Chúng không cần thiết trong bất kỳ vỏ hiện đại nào mà tôi biết. Chúng chắc chắn không được POSIX yêu cầu. Các ví dụ POSIX không sử dụng chúng.
Stéphane Chazelas

3
-deletekhông thể được sử dụng với các thư mục.
St0rM

8

Tôi đoán lý do là findtrước tiên xóa cây thư mục và cố gắng kiểm tra nội dung thư mục rõ ràng không phải là thứ tự tốt nhất có thể. Bạn có thể buộc findphải kiểm tra nội dung trước:

find . -depth ...

Bạn nên xem xét sử dụng -deletecho các tập tin và -exec rmdircho các thư mục.


0

Giải pháp của tôi.

find . -regextype posix-egrep -regex ".*/(obj|build|.+\.so)" -prune -exec rm -rf {} +

+ so với \; trong lệnh -exec


Điều đó không phải lúc nào cũng hoạt động, chỉ khi không có ranh giới giữa các lần thực hiện xảy ra trong một thư mục bị xóa.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles, "ranh giới giữa các vụ hành quyết" nghĩa là gì?
Maksim Dmitriev

1
-exec … {} +thực thi lệnh cho nhiều tệp cùng một lúc, càng nhiều càng phù hợp với dòng lệnh. Nếu có quá nhiều tệp (hoặc chính xác hơn nếu tổng chiều dài của các đường dẫn quá dài), findsẽ thực thi nhiều trường hợp rmvà do đó có thể sẽ xóa một thư mục mà nó đi qua. Nó chỉ ít xảy ra với +hơn ;, nhưng +không giải quyết được vấn đề.
Gilles 'SO- ngừng trở nên xấu xa'
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.