ls bỏ qua không có trận đấu nào


8

Tôi muốn liệt kê tất cả các tệp trong một thư mục được gọi là foldernamecó phần mở rộng test, atesthoặc btest.

Suy nghĩ trước mắt của tôi là chạy ls ./foldername/*.{a,b,}test

Điều này hoạt động tốt trừ khi không có gì với phần mở rộng atest, trong trường hợp đó tôi nhận được lỗi zsh: no matches found: ./foldername/*.atest.

Có cách nào đơn giản là tôi có thể bỏ qua lỗi này và in các tệp tồn tại không?

Tôi cần điều này để làm việc trong cả ZSH và BASH.


3
Chuyển hướng lỗi tiêu chuẩn sang /dev/null?
DopeGhoti

Câu trả lời:


9

Có thể tốt nhất để làm điều này với find:

find ./foldername -maxdepth 1 -name '*.atest' -o -name '*.btest' -o -name '*.test'

1
có lẽ với một -maxdepth 1, để mô phỏng gần hơn lshành vi
Jeff Schaller

4
@JeffSchaller, lưu ý rằng đó -maxdepthlà một phần mở rộng GNU. Lưu ý 3 điểm khác biệt khác với các khối: findsẽ bao gồm các tệp ẩn, không sắp xếp danh sách và không khớp với tên tệp chứa byte không tạo thành các ký tự hợp lệ (như $'St\xe9phane.atest'trong một ngôn ngữ UTF-8)
Stéphane Chazelas

11

Trong

ls -d ./foldername/*.{a,b,}test

{a,b,...} không phải là nhà điều hành toàn cầu, đó là mở rộng cú đúp, lần đầu tiên được mở rộng thành:

ls -d ./foldername/*.atest ./foldername/*.btest ./foldername/*.test

Và mỗi quả cầu được mở rộng riêng lẻ và nếu bất kỳ quả cầu nào không khớp, lệnh sẽ bị hủy như bạn mong đợi zsh(hoặc fish; trong bash, bạn cần failglobtùy chọn để có hành vi tương tự).

Tại đây, bạn muốn sử dụng một quả cầu duy nhất khớp với tất cả các tệp đó và chỉ hủy lệnh nếu một quả cầu đó không khớp với bất kỳ tệp nào:

ls -d ./foldername/*.(a|b|)test

Bạn không muốn sử dụng nullglob, vì nếu không có bất kỳ khối nào phù hợp, nó sẽ chạy lsmà không có đối số, vì vậy hãy liệt kê thư mục hiện tại. cshnullglobtốt hơn về mặt đó vì nó loại bỏ các khối không phù hợp nhưng vẫn hủy lệnh nếu tất cả các khối không khớp.

Bạn sẽ không muốn sử dụng nonomatch, vì điều đó sẽ cho bạn hành vi bị phá vỡ bashsẽ là một sự xấu hổ.

Đối với một giải pháp thay thế toàn cầu hoạt động ở cả hai zshbash, bạn có thể sử dụng các khối ksh ( set -o kshglobtrong zshshopt -s extglobtrong bash).

Sau đó, bạn sẽ làm:

ls -d ./foldername/*.@(a|b|)test

hoặc là:

ls -d ./foldername/*.?([ab])test

Thêm failglobtùy chọn vào bashđể tránh quả cầu được truyền theo nghĩa đen lskhi nó không khớp.

Xem tại sao nullglob không được mặc định? để biết thêm thông tin.


Tôi không chắc tại sao đó là yêu cầu của OP, nhưng có một extglob hoạt động cho điều này trong cả bash và zsh không? Tôi đã phải sử dụng ?(...)hoặc +(...)cho bash.
Jeff Schaller

@JeffSchaller, xem chỉnh sửa
Stéphane Chazelas
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.