Làm cách nào để xóa tất cả các thư mục con trong thư mục?


51

Câu hỏi này thuộc loại giai đoạn II cho câu hỏi đầu tiên tôi đăng ở đây

Tôi có một thư mục chứa một loạt các thư mục con, tệp .zip và các tệp ngẫu nhiên khác không có trong thư mục con.

Tôi muốn một tập lệnh dòng lệnh để xóa tất cả các thư mục con từ trong thư mục mẹ, nhưng giữ tất cả các tệp zip và các tệp lỏng lẻo không thuộc về bất kỳ thư mục con nào. Tất cả các thư mục con đều có nội dung, vì vậy tôi tin rằng tôi cần phải xóa chúng bằng lệnh -f.

Về cơ bản, một lệnh nhìn bên trong thư mục mẹ (hoặc thư mục hiện tại), xóa tất cả các thư mục từ bên trong nó, nhưng giữ tất cả các nội dung và tệp khác không phải là một thư mục hoặc chứa trong một thư mục.

Tôi hiểu rằng việc xóa các mục khỏi dòng lệnh đòi hỏi sự cẩn thận đặc biệt, nhưng tôi đã thực hiện tất cả các biện pháp phòng ngừa cần thiết để sao lưu từ xa.

Câu trả lời:


62

Trong BASH, bạn có thể sử dụng dấu gạch chéo (Tôi nghĩ rằng nó nên hoạt động trong bất kỳ vỏ POSIX nào):

rm -R -- */

Lưu ý --phân tách các tùy chọn khỏi các đối số và cho phép một mục loại bỏ các mục bắt đầu bằng dấu gạch nối - nếu không, sau khi mở rộng bằng vỏ, tên mục nhập sẽ được hiểu là một tùy chọn bởi rm(cùng giữ cho nhiều tiện ích dòng lệnh khác).

Thêm -ftùy chọn nếu bạn không muốn được nhắc xác nhận khi xóa các tệp không thể ghi.

Lưu ý rằng theo mặc định, các thư mục ẩn (những thư mục có tên bắt đầu .) sẽ được để lại một mình.

Một cảnh báo quan trọng: việc mở rộng */cũng sẽ bao gồm các liên kết tượng trưng cuối cùng giải quyết các tệp của thư mục loại . Và tùy thuộc vào việc rmthực hiện, rm -R -- thelink/sẽ chỉ xóa symlink hoặc (trong hầu hết chúng) xóa nội dung của thư mục được liên kết theo cách đệ quy nhưng không phải chính thư mục đó cũng như symlink.

Nếu sử dụng zsh, cách tiếp cận tốt hơn sẽ là sử dụng vòng loại toàn cầu để chỉ chọn các tệp thuộc loại thư mục:

rm -R -- *(/) # or *(D/) to include hidden ones

hoặc là:

rm -R -- *(-/)

để bao gồm các liên kết tượng trưng đến các thư mục (nhưng vì, lần này, bản mở rộng không có dấu vết /, đó chỉ là liên kết tượng trưng được loại bỏ với tất cả các rmcài đặt).

Với bash, AT & T ksh, yashhoặc zshbạn có thể làm:

set -- */
rm -R -- "${@%/}"

để thoát khỏi dấu vết /.


Đẹp! Điều này hoạt động hoàn hảo. Tôi đã không nhận ra nó rất dễ làm. Bạn có phiền khi xây dựng trên -r so với -R và những lệnh đó làm gì không? Cảm ơn nhiều.
Evster

-r, -R, --recursiveLà từ đồng nghĩa có nghĩa là "thư mục remove và nội dung của đệ quy".
peterph

bạn có thể giải thích những gì - và * / làm không?
đổ bộ

6
Bạn cũng có thể nói rm -R ./*/- Nó cũng tránh các vấn đề với tên gạch nối.
l0b0

1
Chỉ cần cẩn thận không thay đổi thứ tự của * và /. rm -R - / * làm điều gì đó hoàn toàn khác mà bạn có thể không muốn xảy ra: |
ChrisOdney

13

Ngoài cách ký tự đại diện, bạn cũng có thể sử dụng find(ít nhất là GNU find) để làm điều này:

find -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 rm -R

Cũng như các finddòng khác , bạn có thể chạy phần đầu tiên ( find -mindepth 1 -maxdepth 1 -type d) để xem danh sách các thư mục sẽ bị xóa.

Một lựa chọn an toàn hơn là làm một cái gì đó như thế này:

find -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 mv -i -t ../to-rm
# or
mv -i -t ../to-rm */
# or
mv -i */ ../to-rm

bất kỳ trong số đó sẽ di chuyển tất cả các công cụ vào ../to-rmthay vì xóa nó. Bạn có thể xác minh nó đã làm những gì bạn muốn, rm -Rfthư mục đó lúc rảnh rỗi.


+1 cho "Thùng rác CLI" to-rmfindxử lý độc đáo các thư mục bắt đầu bằng dấu chấm (ngoài bất kỳ lối thoát rườm rà nào khác). :)
peterph 22/03/13

Cảm ơn vì tiền hỗ trợ. Tôi thích ý tưởng di chuyển đến một thư mục riêng trước khi xóa. Tôi đang làm việc thông qua Terminal trên Mac OS X và tôi tin rằng tôi cần cài đặt một số loại gói GNU để sử dụng các lệnh -mindepth và -maxdepth, đúng không?
Evster

@Evster không chắc chắn nếu Mac OS X find hỗ trợ những thứ đó. Tôi đoán fink (vẫn còn đó?) Có thể cài đặt một tìm thấy mà. Hoặc bạn có thể bỏ qua chúng, sau đó lọc danh sách tệp được tạo bằng grep. Chắc chắn sử dụng tùy chọn mv trên đó, istead của rm.
derobert

4

Bạn có thể muốn tạo một tập lệnh cho một số đề xuất này, đặc biệt rm -R -- */, và giữ nó trong thư mục / usr / local / bin của bạn; hoặc tạo một aliastệp trong tập tin ~ / .bashrc của bạn. Vì thật dễ dàng để gõ nhầm một lệnh và phá vỡ hệ thống của bạn - ngay cả một chữ cái và / hoặc thứ tự các chữ cái có thể dẫn đến hậu quả thảm khốc - điều này sẽ phục vụ như một giải pháp mạnh mẽ hơn so với việc phải nhập các tùy chọn và đối số khác nhau mỗi lần bạn muốn hoàn thành nhiệm vụ này.

Ngoài ra, bạn có thể muốn bao gồm -i or --interactive=oncehoặc -I or --interactive=alwaystùy chọn cho tập lệnh / lệnh sẽ đóng vai trò là một công cụ khác để tránh việc xóa ngoài ý muốn.

Hơn nữa, một cái gì đó như derobert đề nghị sẽ là tốt nhất; chỉ cần sao chép / dán tập lệnh vào một tập tin / trình soạn thảo đầu cuối và điều chỉnh nó theo nhu cầu cụ thể của bạn và các tập tin / thư mục sẽ được chuyển vào một thư mục duy nhất (nội dung mà bạn có thể kiểm tra / xác minh) mà bạn có thể xóa bằng cách đơn giản ban hành rm -rflệnh.

Một tùy chọn khác là sử dụng ứng dụng GUI, chẳng hạn như trình quản lý tệp của bạn và chỉ cần chọn tất cả các tệp / thư mục có thể áp dụng mà bạn muốn xóa. Kiểm tra các trang hướng dẫn phân phối của bạn nếu bạn không có quyền.

Cuối cùng, nếu các thư mục trống - về cơ bản là tên tệp đơn giản - bạn có thể sử dụng rmdirlệnh để xóa chúng. Nó không hoạt động cho tất cả mọi thứ bạn có thể muốn xóa, nhưng nó sẽ có ích vào những lúc bạn muốn thực hiện một số "dọn dẹp nhà cửa". ** Bạn có thể muốn thử -p --ignore-fail-on-non-emptytùy chọn này, điều này sẽ cho phép bạn xóa một số thư mục con nhất định cũng như "cha mẹ" trống rỗng của chúng - các thư mục mà chúng cư trú.


Đó là một ý tưởng thực sự tốt về việc tạo một tập lệnh riêng biệt mà tôi có thể gọi cho lệnh này. Bạn có thể giải thích chính xác các tùy chọn -i và -I làm gì không? Cảm ơn!
Evster

-Tôi tùy chọn sẽ nhắc bạn một lần sau khi bạn nhấn "Enter" để xác nhận rằng bạn muốn xóa cái này (khi có hơn 3 tệp / thư mục "được chọn"); trong khi tùy chọn -i sẽ đưa ra lời nhắc cho từng tệp, khi đó bạn có thể chỉ cần xác nhận bằng cách nhấn "y" và "Enter" - bất cứ điều gì ngoài phản hồi khẳng định sẽ dẫn đến việc tệp cụ thể bị bỏ qua trong quá trình xóa.
ILMostro_7

1

Trước tiên, bạn cần liệt kê các thư mục và sau đó loại bỏ chúng, mà không cản trở các tệp bình thường, ls -d * /, chỉ liệt kê các thư mục con và đường ống với rm sẽ xóa các thư mục và nội dung, giữ nguyên các tệp lỏng lẻo.

Lệnh này sẽ thực hiện công việc,

ls -d  */ | xargs rm -rf

1
Điều gì sẽ là lợi ích hơn rm -rf -- */? printf '%s\0' */ | xargs -r0 rm -rf --sẽ giúp (trong các shell printfđược tích hợp và không ls) hoạt động xung quanh danh sách các lỗi quá lớn , nhưng ls -d */ | xargs rm -rfkhông thêm bất cứ điều gì AFAICT ngoại trừ các vấn đề bổ sung.
Stéphane Chazelas

1
@AnthonyGeoghegan, vâng, ví dụ nếu có một thư mục được gọi là " .."(dấu cách ..), nó sẽ xóa nội dung của thư mục mẹ với một số lstriển khai. Và nó không chỉ là khoảng trắng, mà còn là các ký tự trống khác, dòng mới, trích dẫn đơn, trích dẫn kép, dấu gạch chéo ngược và tên tệp bắt đầu bằng -.
Stéphane Chazelas

2
@Ankit, bạn có thể bắt đầu với mywiki.wooledge.org/ParsingLs
Stéphane Chazelas

1
Khi bạn hoàn toàn hiểu @ đề nghị StéphaneChazelas' của việc sử dụng printfđể tạo ra một danh sách trong đó mỗi tên được chấm dứt bởi ký tự null để nó có thể được xử lý bởi xargsvới -0lựa chọn, tôi muốn khuyên bạn chỉnh sửa câu trả lời của bạn để cập nhật nó với sự thay đổi của mình. Tôi khá tự tin rằng anh ấy sẽ rất vui khi bạn sử dụng đoạn mã của anh ấy nếu bạn hiểu và đã học được cách nó bảo vệ chống lại hành vi không mong muốn gây ra bởi một số tên tệp có khả năng tồn tại.
Anthony G - công lý cho Monica

1
Việc sử dụng xargscó một lợi thế so với câu trả lời được chấp nhận (nó hoạt động khi có một số lượng rất lớn các tệp / thư mục trong thư mục hiện tại) vì vậy có phạm vi để chỉnh sửa câu trả lời này thành một câu trả lời hữu ích. Cá nhân, tôi thấy việc trả lời các câu hỏi của Stack Exchange là một trải nghiệm học tập tốt - đặc biệt là khi tôi nhận được phản hồi hữu ích từ những người dùng khác.
Anthony G - công lý cho Monica

-1

rm -rf <directory name>. Nó hoạt động. Chỉ cần gõ rm <directory name>chỉ dẫn đến số lượng câu hỏi phụ trong đó mỗi thư mục con phải được loại bỏ bằng tay. Nhưng, rm -rfgiúp loại bỏ toàn bộ thư mục cùng với các thư mục con cùng một lúc.


5
OP yêu cầu giữ nội dung của thư mục hiện tại.
Stephen Rauch
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.