Trong linux, làm thế nào để xóa tất cả các tệp NGOẠI TRỪ mẫu * .txt?


74

Tôi biết làm thế nào để xóa tất cả các txttập tin trong thư mục hiện tại bằng cách rm *.txt. Có ai biết làm thế nào để xóa tất cả các tập tin trong thư mục hiện tại txttập tin EXCEPT ?


21
Như mọi khi, hãy kiểm tra các câu trả lời đã cho bằng một lệnh vô hại như lstrước khi thực sự cố gắng gọi rm.
chepner

^ Anh chàng này không thích sống nguy hiểm .. :)
jDub9

Câu trả lời:


111

Bạn có thể sử dụng find:

find . -type f ! -name '*.txt' -delete

Hoặc các tính năng toàn cầu mở rộng của bash:

shopt -s extglob
rm *.!(txt)

Hoặc trong zsh:

setopt extendedglob
rm *~*.txt(.)
#  ||     ^^^ Only plain files
#  ||^^^^^ files ending in ".txt"
#  | \Except
#   \Everything

Một số trong số này có thể cần được điều chỉnh tùy thuộc vào việc bạn có thư mục hay không và bạn muốn làm gì với chúng.
Kevin

1
Không nên *.!(txt)!(*.txt)?
Lri

@LauriRanta phụ thuộc vào những gì trong thư mục mà chúng tôi chưa nhận được câu trả lời. Sẽ tốt nếu như tất cả các tệp đều có tiện ích mở rộng và rmsẽ bị nghẹt nếu có thư mục.
Kevin

Tôi đã có một vấn đề với dấu ngoặc. Khi tôi sử dụng kiểu globalbing trong tập lệnh bash, nó sẽ phàn nàn về lỗi cú pháp và dấu ngoặc đơn. Tuy nhiên, làm điều đó từ CLI hoạt động.
CMCDragonkai

1
@izogfif kiểm tra cái này find . -type f ! -name "*.txt" | xargs -r rmsẽ hoạt động trong GNU \ xargs. Lệnh xargs BSD và UNIX có thể không có -r bạn phải kiểm tra cục bộ của mìnhman xargs
Ntwobike

10

có nhiều cách có thể làm điều đó. nhưng cách đơn giản nhất sẽ là (bash):

shopt -s extglob
rm !(*.txt)

10

Nếu bạn chỉ muốn xóa tất cả các tệp ngoại trừ '* .txt' thì bạn có thể sử dụng lệnh sau:

$ find . -type f ! -name "*.txt" -exec rm -rf {} \;

nhưng nếu bạn cũng muốn xóa các thư mục cùng với các tệp thì bạn có thể sử dụng điều này:

$ find . ! -name "*.txt" -exec rm -r {} \;


4

Một giải pháp không có find:

mv dir/*.txt otherdir/
rm -r dir
mv otherdir dir

Điều này sẽ làm việc trên tất cả các loại vỏ.


3

Bạn có thể sử dụng grep và xarg ngược

ls | grep -v .txt$| xargs rm

ls | grep -v *.txt | xargs rmcũng hoạt động tốt
phillipsk

@phillipsk grep -v *.txtsẽ chỉ hoạt động nếu có chính xác một .txttệp. Nếu không có, grepsẽ sử dụng *.txtlàm mẫu; nếu có nhiều hơn một, nó sẽ tìm kiếm tên tệp đầu tiên bên trong tất cả các .txttệp khác , bỏ qua đầu ra từ ls. (Kết quả chính xác có thể phụ thuộc vào tùy chọn toàn cầu của hệ vỏ.)
JigglyNaga

.txt$sẽ khớp chuỗi kết thúc với txtbất kể dấu chấm. Bởi vì greplấy biểu thức chính quy làm tham số. Vì vậy, các file a.txtaatxta-txttất cả sẽ được kết hợp bởi biểu thức này. Biểu thức đúng nên được ls | grep -v \\.txt$ | xargs --no-run-if-empty rm. Đối với những người tò mò: Nếu bạn muốn chơi xung quanh với biểu thức một cách an toàn, hãy sử dụng biểu thức kiểm tra này ls | grep \\.txt$ | xargs --no-run-if-empty echo(lưu ý: không có -vcờ và rm=>echo). Lưu ý2: bạn có thể đã nhận thấy dấu gạch chéo kép. Một là cho regex, một là cho bash để thoát dấu gạch chéo.
Dimitry K

1

Đơn giản chỉ cần làm:

rm $(ls -I "*.txt" ) Loại tệp #Deletes ngoại trừ * .txt

Tương tự, nếu cần xóa "ngoại trừ một hoặc nhiều loại tệp", hãy:

rm $(ls -I "*.txt" -I "*.pdf" ) Các loại tệp #Deletes ngoại trừ * .txt & * .pdf


Chào mừng bạn đến với StackExchange! Các -Itùy chọn có thể hữu ích, nhưng nhìn thấy lý do tại sao không phân tích ls . Và những gì | xargsđạt được? Không có bất kỳ đối số, nó chỉ chạy echotrên tất cả các đầu vào của nó.
JigglyNaga

Những gì được xargscho là để đạt được?
dhag

Cảm ơn, xargs không hữu ích trong trường hợp trên, đã sửa ngay bây giờ.
Surya

0

Điều này cũng hoạt động để loại bỏ tất cả các tệp và thư mục bị ẩn (dấu chấm) ngoại trừ tệp đã nêu ( .mydir):

rm -rf $(ls -aI ".mydir")
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.