rm -rf tất cả các tệp và tất cả các tệp ẩn mà không có. & .. lỗi


83

rm -rf /some/path/* xóa tất cả các tệp không bị ẩn trong thư mục đó (và các thư mục con).

rm -rf /some/path/.* xóa tất cả các tệp bị ẩn trong thư mục đó (nhưng không phải là thư mục con) và cũng đưa ra lỗi / cảnh báo sau:

rm: cannot remove directory: `/some/dir/.'
rm: cannot remove directory: `/some/dir/..'

Cách thích hợp để loại bỏ tất cả các tệp và thư mục ẩn và không ẩn theo cách đệ quy trong một thư mục đích mà không nhận được cảnh báo / lỗi về .và là ..gì?

Câu trả lời:


40

Bạn luôn có thể gửi thông báo lỗi đến /dev/null

rm -rf /some/path/.* 2> /dev/null

Bạn cũng có thể

rm -rf /some/path/
mkdir /some/path/

... Sau đó, bạn sẽ không phải bận tâm với các tập tin ẩn ở nơi đầu tiên.


2
Nhưng nếu tôi chỉ muốn xóa các tập tin ẩn thì sao?
CMCDragonkai

@CMCDragonkai nên là một câu hỏi khác, nhưng bạn có thể tìm thấy giải pháp trong câu trả lời của Gilles ( rm ..?* .[!.]*nên làm điều đó).
evilsoup

15
Không xóa và tạo lại thư mục có nguy cơ rằng các quyền của tệp không ngay sau đó (đặc biệt quan trọng trong môi trường máy chủ). Ai có thể tự động tạo thư mục có cùng quyền như trước?
Yo Ludke

1
@YoLudke Bạn hoàn toàn chính xác, trong nhiều trường hợp không thành vấn đề nhưng việc xóa thư mục và tạo lại không tương đương về mặt ngữ nghĩa với việc làm trống thư mục đó; vì vậy hãy cẩn thận làm điều đó
Thomas

Xóa thư mục không phải lúc nào cũng có thể. Trong trường hợp của tôi, thư mục là một khối docker, và trong khi tôi có thể làm bất cứ điều gì tôi muốn bên trong âm lượng, tôi không thể thay đổi âm lượng từ bên trong container.
dovidweisz

85

*khớp với tất cả các tệp không có dấu chấm, .[!.]*khớp với tất cả các tệp dấu chấm trừ .và các tệp có tên bắt đầu ....?*khớp với tất cả các tệp dấu chấm trừ ... Họ cùng nhau phù hợp với tất cả các tập tin khác .... Nếu bất kỳ mẫu nào trong ba mẫu này không khớp với nhau, nó sẽ tự mở rộng; rm -fkhông quan tâm đến các đối số không tồn tại, vì vậy điều này không quan trọng.

rm -rf ..?* .[!.]* *

Bạn cũng có thể sử dụng find. Điều này phức tạp hơn nhưng có lợi thế hoạt động ngay cả khi có rất nhiều tệp mà các ký tự đại diện ở trên sẽ mở rộng vượt quá giới hạn độ dài dòng lệnh của hệ thống của bạn.

find . -name . -o -prune -exec rm -rf -- {} +

Bạn có thể thấy rõ hơn để loại bỏ và tạo lại thư mục. Điều này có lợi thế (hoặc nhược điểm, như trường hợp có thể) dẫn đến một thư mục trống ngay cả khi một chương trình khác đang đồng thời tạo các tệp trong thư mục gốc.


8
Đây phải là câu trả lời được chấp nhận, vì nó ngăn chặn việc xóa ngang và xóa có thể xảy ra.
rbellamy

Các findlựa chọn trả về "thành công" ngay cả khi một số tập tin không được xóa thành công; không tốt cho kịch bản
Franklin Yu

Liên quan đến findlệnh thứ hai của bạn , trang quản lý tìm trạng thái "Bởi vì -delete ngụ ý -depth, bạn không thể sử dụng hữu ích -prune và -delete cùng nhau." - bạn dùng -prune -deletechưa?
Doktor J

@DoktorJ Thật vậy, -prunekhông làm gì ở đây cả. Và khi đọc lại tôi thấy rằng tôi đã không trả lời chính xác câu hỏi: Tôi đã cẩn thận không tái diễn, nhưng câu hỏi rõ ràng yêu cầu xóa đệ quy. Tôi đã sửa câu trả lời của mình.
Gilles

2
@haylem Trong zsh, bạn cần viết .[^.]*thay vì .[!.]*khi bật lịch sử thay thế (theo mặc định là trường hợp tương tác nhưng không phải trong tập lệnh), vì zsh phân tích !như một tham chiếu lịch sử. Nhưng trong zsh bạn sẽ không cần điều đó ở nơi đầu tiên, bạn chỉ có thể sử dụng *(D)để bao gồm các tệp chấm (không có .hoặc ..) trong kết hợp ký tự đại diện.
Gilles

21

Chỉ cần nhận ra đây là cách thuận tiện nhất trong hầu hết các bản phân phối Linux:

ls -A1 | xargs rm -rf

Ở đâu

-A= liệt kê mọi thứ trừ ...

-1 = đặt mọi mục trong một dòng


4
Nhược điểm mà tôi thấy là: bạn cần 'cd' vào thư mục để làm điều này.
kumar

ls -A1 /your/path/ | xargs rm -rfnên áp dụng
godzillante

không..tôi không giúp - Ví dụ: ls -A1 ~ / test / | xargs rm -rf lệnh này sẽ xóa các tệp mà tôi hiện đang 'cd vào' .. không có trong thư mục ~ / test.
kumar

5
Nó không hoạt động nếu bất kỳ tên tệp nào chứa khoảng trắng, dòng mới, dấu ngoặc kép hoặc dấu gạch chéo ngược.
Stéphane Chazelas

1
-1 Vì nhận xét trên. ↑↑↑↑↑↑↑↑
somethingSomething

15

Hoặc thay đổi dotglobtùy chọn vỏ của bạn và sử dụng *, hoặc sử dụng một cái gì đó như find.

find somedir -mindepth 1 -delete

2
Hoặc bạn có thể đơn giản rm -rf /some/dirvà sau đó tạo một thư mục trống mới ở vị trí của nó.
tripleee

Lựa chọn tốt nhất cho đến nay. Rất an toàn vì bạn chỉ định rõ ràng đường dẫn thư mục.
Yanick Girouard

4

Điều này sẽ hoạt động giống như câu trả lời @Gilles nhưng nhỏ gọn hơn:

rm -rf {,.[!.],..?}*

hoặc là

rm -rf dir/to/files/{,.[!.],..?}*

cũng nên thêm một ifcách sử dụng trong các tập lệnh để an toàn:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi

1
Thật kỳ lạ, như một bí danh bash trên Ubuntu 16.04 LTS, câu trả lời trước đó không hoạt động. Tuy nhiên, alias cleandir='rm -rf {,.[!.],..?}*'không.
Steven Ventimiglia

3

Tìm là bạn của bạn.

find ! -name '.' ! -name '..' -delete

% find ! -name '.' ! -name '..'
./test
./test4
./test4/.test6
./test3
./.test5
./test2
% find ! -name '.' ! -name '..' -delete    
% find ! -name '.' ! -name '..'     
%             

Nếu bạn muốn sử dụng đệ quy tìm kiếm một cái gì đó khác thư mục hiện tại của bạn ($ PWD), sau đó thêm một đường dẫn ngay sau findlệnh; ví dụ find /path ! -name '.' ! -name '..' -delete. Nếu bạn chỉ muốn giảm nsố lượng thư mục, thì hãy sử dụng -maxdepth ntùy chọn ngay sau /paththam số.

Lệnh trên đã được thử nghiệm trên hệ thống Ubuntu 13.04. Sẽ có khả năng làm việc trên các hệ thống linux hiện đại khác.


để xóa tất cả các thư mục trong thư mục hiện tại bạn có thể làmfind . ! -name '.' ! -name '..' -type d -delete
Andy

2

Cách thích hợp để loại bỏ tất cả các tệp và thư mục ẩn và không ẩn theo cách đệ quy trong một thư mục đích mà không nhận được cảnh báo / lỗi về. và ..?

Giả sử thư mục trong câu hỏi là ./dir, sau đó

rm -rf ./dir

sẽ xóa tất cả các tệp trong ./dir, bao gồm các tệp và thư mục ẩn, theo cách đệ quy và bao gồm cả ./dirchính thư mục đó.

Nếu bạn không muốn xóa thư mục đó, thì bạn có thể tạo lại nó sau đó hoặc sử dụng

find ./dir -mindepth 1 -delete

hoặc nếu bạn findkhông hỗ trợ -delete,

find ./dir -mindepth 1 -depth -exec rm -rf {} ';'

Sử dụng -mindepth 1cho phép bạn giữ thư mục cấp cao nhất ./dir.


điều này nên được đánh dấu là câu trả lời hay nhất
kitingChris

1

Tôi đề nghị bạn thử nghiệm với

Turn- ON chấm (file ẩn)

  • bộ dotglob

    shopt -s dotglob

Turn- OFF chấm

  • không đặt dotglob

    shopt -u dotglob

Phương pháp này hoạt động chính xác như tôi muốn cho một lệnh sao chép bị thiếu các thư mục ẩn.

    shopt -s    dotglob
    cp    -rvn  ./$from/*  ./$too/
    shopt -u    dotglob

Vì vậy, tôi đã xóa (xóa) và rất tiếc ...

    shopt -s    dotglob
    rm -fr ../message_splitter--044a/*
    shopt -u    dotglob

... cũng hoạt động!

Nó xảy ra với tôi rằng bạn đọc thân yêu không thể xem message_splitterthư mục. Bất kỳ cách nào nó cũng có một .svnthư mục cần được loại bỏ và sao chép vào.

Từ mantrang ...

dotglob Nếu được đặt, bash bao gồm tên tệp bắt đầu bằng một `. ' trong kết quả mở rộng tên đường dẫn.

người giới thiệu:


-2

Hãy thử mã này:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
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.