Xóa tất cả trừ một (hoặc nhiều) loại filetype


20

Tôi đã cố gắng tìm một lệnh để loại bỏ tất cả các tệp trong một thư mục nhưng không phải là một loại tệp. Nhưng tôi dường như không có may mắn. Những gì tôi đã cố gắng cho đến nay:

set extended_glob
rm !(*.dmg)
# this returns zsh:number expected

rm ./^*.dmg
# this returns no matches found 

Phiên bản của zsh tôi đang sử dụng là zsh 5.0.2 (x86_64-apple-darwin13.0.1).

Câu trả lời:


22

Các extended_globtùy chọn cho phép bạn mở rộng zsh riêng của cú pháp glob .

setopt extended_glob
rm -- ^*.dmg
rm -- ^*.(dmg|txt)

Bạn có thể thiết lập ksh_globtùy chọn để có được ksh globs . Xin lưu ý rằng trong trường hợp phổ biến trong đó mẫu âm là điều cuối cùng trong từ, zsh có thể phân tích dấu ngoặc đơn là vòng loại toàn cầu (nó không làm điều này trong chế độ mô phỏng ksh).

setopt ksh_glob
rm -- !(*.dmg|*.txt)
setopt no_bare_glob_qual
rm -- !(*.dmg)

Điều này dường như không hoạt động. Khi tôi chạy, rm -r secrets/!(directory)nó cứ hỏi number expectedhoặc đôi khi nó mang lại cho tôievent not found: directory
CMCDragonkai

Số @CMCDragonkai Số lượt mong đợi cho thấy bạn không đặt ksh_globtùy chọn. Không tìm thấy sự kiện: thư mục Chỉ ra rằng bạn đang chạy bash (cũng hiểu !(…)cú pháp, nhưng chỉ sau shopt -s extglob).
Gilles 'SO- ngừng trở nên xấu xa'

Làm thế nào tôi có thể chạy bash khi tôi ở trong vỏ zsh của tôi?
CMCDragonkai

Đối với tôi, setopt ksh_glob; echo !(a|b)hoạt động trong khi setopt ksh_glob; echo !(a)không ("số lượng dự kiến") ...
ThiefMaster

@ThiefMaster Tôi có vấn đề tương tự. Có phải là một lỗi?
CodeTower

5

Bạn có thể sử dụng findthay vì vỏ của bạn:

find . -mindepth 1 -maxdepth 1 ! -name "*.dmg" -delete

Từ man find:

   ! expr True  if  expr  is false.  This character will also usually need
          protection from interpretation by the shell.
   -name pattern
          Base of file name (the path with the leading directories removed)
          matches shell pattern pattern. 
   -delete
          Delete  files; true if removal succeeded.  If the removal failed,
          an error message is issued.  If -delete fails, find's exit status
          will be nonzero (when  it eventually exits).  Use of -delete 
          automatically turns on the -depth option.

Nếu bạn không thể sử dụng findvì bất kỳ lý do gì, đây là một cách để làm điều đó với zsh(hoặc các vỏ khác). zshzsh, có lẽ là một cách đơn giản hơn để làm điều này nhưng kể từ khi tôi là một bashchàng trai, đây là những gì tôi đã đưa ra:

for file in *; do if [[ ! "$file" == *.dmg ]]; then rm $file; fi; done

Thật không may, bất cứ khi nào tôi sử dụng find trong mac của mình, nó chỉ thoát khỏi phiên zsh hiện tại mà không có bất kỳ thông báo nào. Bạn có vấn đề tương tự ? find [Process completed]
Dzung Nguyễn

1
@nXqd xem câu trả lời cập nhật để biết cách thực hiện mà không cần find. Tôi đề nghị bạn gửi một câu hỏi về findvấn đề của bạn , điều đó không nên xảy ra. Nếu bạn làm, bao gồm đầu ra của type -a find.
terdon

1
Ngay cả trong bash, có một giải pháp đơn giản hơn : rm !(*.dmg), sau shopt -s extglob.
Gilles 'SO- ngừng trở nên xấu xa'

@terdon cảm ơn lời khuyên gỡ lỗi của bạn trong shell. đầu ra của nó có vẻ đúng:find is a shell function find is /usr/bin/find
Dzung Nguyen

@nXqd không đúng, nó không phải là hàm shell, chỉ nên là vậy /usr/bin/find. Bạn có một hàm được gọi là findđược xác định trong một trong các tệp cấu hình bash của bạn. Vì bạn đang dùng OSX, có lẽ vậy ~/.profile.
terdon

3

Một cách khác để xóa tệp là với find, xargsrm:

find . -mindepth 1 -maxdepth 1 ! -name '*.dmg' -print0 | xargs -0 rm
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.