2011-12-15 27 views
46

Sau đây là cách người ta có thể liệt kê tất cả các file phù hợp với một mô hình trong bash:Liệt kê các tệp không khớp với mẫu?

ls *.jar 

Làm thế nào để liệt kê các bổ sung của một mô hình? nghĩa là tất cả các tệp không khớp với * .jar? Ví dụ:

+0

điều này có lẽ không nên được gắn nhãn regex, * là một ký tự đại diện vỏ sò, và không phải là cụm từ thông dụng *, là "số không hoặc nhiều hơn". – sweaver2112

+0

Điểm tốt, mặc dù tôi đang học rằng sử dụng regex có lẽ là thực hành tốt hơn để có được các trận đấu bạn mong đợi. – paislee

Trả lời

38
ls | grep -v '\.jar$' 

chẳng hạn.

+2

Cờ -v cho grep là gì? – paislee

+12

kết quả đảo ngược. Ngoài ra còn có một 'người đàn ông grep'. –

+0

Làm cách nào để bạn có thể thực hiện hai loại tệp? – Dan

2

Một giải pháp sẽ được ls -1|grep -v '\.jar$'

+0

[Không phân tích đầu ra của 'ls'] (http://mywiki.wooledge.org/ParsingLs), cảm ơn bạn. –

+6

@gniourf_gniourf không tôn trọng các quy tắc như phân tích cú pháp 'ls' hoặc sử dụng' goto'. Đôi khi các giải pháp đó hoạt động tốt nhất. –

+1

Đây không phải là một trong những trường hợp đó; 'tìm. -print0 | grep -z '\ .jar $' 'hoạt động tốt hơn ngay cả khi bạn không muốn sử dụng' --ignore' hoặc hình cầu mở rộng của Bash. Điều đó nói rằng, hầu hết mọi người không muốn đọc toàn bộ bài viết để hiểu quy tắc hoặc những gì họ * nên làm và bạn có thể phù hợp với lời giải thích đơn giản và đề xuất như “nó không hoạt động trong các trường hợp cạnh; sử dụng 'find -print0' và' grep -z' thay vào đó trong một chú thích. –

13

Với một phiên bản thích hợp của find, bạn có thể làm một cái gì đó như thế này, nhưng đó là một overkill chút:

find . -maxdepth 1 ! -name '*.jar' 

find tìm thấy tập tin. Đối số . chỉ định bạn muốn bắt đầu tìm kiếm từ ., tức là thư mục hiện tại. -maxdepth 1 cho biết bạn chỉ muốn tìm kiếm một cấp độ sâu, tức là thư mục hiện tại. ! -name '*.jar' tìm tất cả các tệp mà không khớp với regex *.jar. Như tôi đã nói, đó là một chút quá mức cần thiết cho ứng dụng này, nhưng nếu bạn loại bỏ -maxdepth 1, sau đó bạn có thể tìm kiếm đệ quy tất cả các tệp không phải là tệp jar hoặc những gì bạn có thể dễ dàng.

27

Ít được biết đến quy tắc mở rộng bash:

ls !(*.jar) 
+2

bash:!: Không tìm thấy sự kiện. Tôi cân nhưng gi? – paislee

+6

Hãy thử thực hiện 'shopt -s extglob' trên dòng lệnh trước, sau đó gõ lệnh. –

58

Sử dụng egrep kiểu mẫu mở rộng phù hợp.

ls !(*.jar) 

Điều này có sẵn bắt đầu bằng bash-2.02-alpha1. Trước hết phải được kích hoạt với

shopt -s extglob 

Tính đến bash-4,1-alpha có một tùy chọn cấu hình để cho phép này theo mặc định.

+1

Yay vì đã đề cập đến shopt -s extglob! –

+2

Đây là câu trả lời đúng. Câu trả lời được đánh dấu là chính xác không sử dụng trực tiếp trình bao, nó sử dụng một lệnh phụ trợ. – dbn

+0

@dbw - Ngay cả khi tôi thích câu trả lời này nhiều hơn, câu trả lời được chấp nhận là ok cho câu hỏi. OP không đặc biệt yêu cầu sử dụng "vỏ trực tiếp". –

14

POSIX xác định biểu thức khung không phù hợp, vì vậy chúng tôi có thể cho phép trình bao mở rộng tên tệp cho chúng tôi.

ls *[!j][!a][!r] 

Điều này có một số quirks mặc dù, nhưng ít nhất nó tương thích với bất kỳ vỏ unix nào.

+0

+1 để tuân thủ POSIX. Một hàm bash/python/ruby ​​nhỏ kết hợp với bí danh, tức là. "lsnot" có thể làm cho nó dễ dàng hoàn toàn khả thi. – Nikkolasg

+0

Điều này không khớp với mọi thứ ngắn hơn ba ký tự. –

1

Và nếu bạn muốn loại trừ nhiều hơn một đuôi tệp, hãy tách riêng chúng bằng một đường ống |, như ls test/!(*.jar|*.bar). Hãy thử:

$ mkdir test 
$ touch test/1.jar test/1.bar test/1.foo 
$ ls test/!(*.jar|*.bar) 
test/1.foo 

Trước tiên hãy xem các câu trả lời khác mà bạn có thể cần đến shopt -s extglob.

+1

Bạn có thể rút ngắn giá trị này thành '! (*. [Bj] ar)' thay thế. –

Các vấn đề liên quan