Nhiều phạm vi của các tệp theo thứ tự từ điển trong zsh


24

Tôi muốn chỉ định một phạm vi các tệp (theo thứ tự từ điển) với hai số nguyên (ví dụ 2 đến 57) trong zsh bằng cách nối.

Ví dụ: "chọn các tệp từ 2 đến 57 theo thứ tự từ điển theo đường dẫn khớp với một số mẫu hình cầu".

Tôi nghĩ rằng sử dụng dấu ngoặc vuông sẽ làm điều đó

 for x in /foo/bar/*[2-57]; do print $x; done

nhưng Zsh dường như nghĩ rằng tôi đang yêu cầu các tập tin 2để 5(hoặc một cái gì đó như thế) thay vì các tập tin 2để 57. Bất cứ suy nghĩ tại sao? Làm thế nào tôi có thể thực hiện điều này?

Câu trả lời:


30

[2-57]là một bộ ký tự bao gồm 2, 3, 4, 57, trong zsh và mỗi ký tự đại diện khác và cú pháp regexp ra khỏi đó. Mẫu hình cầu của bạn *[2-57]khớp với mọi tên tệp có ký tự cuối cùng là một trong năm chữ số đó.

Tôi nghĩ rằng bạn đang đánh giá sai cú pháp của [m,n] vòng loại toàn cầu . Vòng loại Glob luôn đi trong ngoặc đơn ở cuối mẫu và dấu phân cách phạm vi là dấu phẩy. Mô hình *([2,57])mở rộng đến các trận đấu thứ 2, 3, tầm, 57. Thứ tự mở rộng mặc định là từ điển (với một số phép thuật đặc biệt để sắp xếp các số theo thứ tự số nếu numeric_glob_sorttùy chọn được đặt); bạn có thể kiểm soát nó bằng ohoặc Ovòng loại toàn cầu (ví dụ: *(om[2,57])để khớp với 57 tệp gần đây nhất ngoại trừ một tệp gần đây nhất).

for x in /foo/bar/*([2,57]); do print $x; done

Không phải những gì bạn yêu cầu, nhưng có liên quan và có thể hữu ích cho những người đọc trong tương lai: nếu bạn muốn liệt kê các tệp từ 2 đến 57 cho dù chúng có tồn tại hay không, bạn có thể sử dụng biểu thức dấu ngoặc kép . Tính năng này cũng tồn tại trong bash và ksh.

echo hello{2..57}

Và nếu bạn muốn khớp các tệp có tên chứa một số từ 2 đến 57, bạn có thể sử dụng mẫu <2-57>. Điều này là cụ thể cho zsh.

$ ls
file1 file2 file3 file57 file58
$ echo file<2-57>
file2 file3 file57

Lưu ý rằng một mẫu như *<2-57>có khả năng không làm những gì bạn mong đợi, bởi vì các mẫu *cũng có thể khớp với các chữ số. Ví dụ, file58phù hợp *<2-57>với file5phù hợp với các *bộ phận và 8phù hợp với các <2-57>bộ phận. Các mô hình *[^0-9]<2-57>tránh vấn đề này.


Bạn đúng rồi. Tôi đã đánh giá sai vòng loại toàn cầu. Cảm ơn đã giải thích cẩn thận.
Amelio Vazquez-Reina

Nhân tiện, câu nói này khiến tôi hơi bối rối : if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression. Nếu các tệp không tồn tại và không có kết quả khớp, thì mở rộng dấu ngoặc sẽ biết cách mở rộng như thế nào? (làm thế nào nó mở rộng khác với vòng loại toàn cầu?)
Amelio Vazquez-Reina

2
@intrpc foo{8..11}barmở rộng tới foo8bar foo9bar foo10bar foo11bar. Bit mở rộng này không liên quan đến tên tệp. Tương tự, foo{eight,nine,ten,eleven}barmở rộng đến fooeightbar fooninebar footenbar fooelevenbar. Đây là mở rộng cú đúp trong ksh / bash / zsh.
Gilles 'SO- ngừng trở nên xấu xa'

6

nhưng zsh rõ ràng nghĩ rằng tôi đang yêu cầu các tệp 2 đến 5 (hoặc một cái gì đó tương tự) thay vì các tệp 2 đến 57. Bạn có suy nghĩ gì không?

Bởi vì []dấu ngoặc chỉ danh sách các ký tự trùng khớp (có thể là chữ số), không phải là số được giải thích theo toán học. Mô hình như vậy được kết hợp với một nhân vật duy nhất . Danh sách có thể chứa phạm vi, nhưng chữ số hoặc chữ cái. [2-57]trận đấu mở rộng thành "Tất cả các chữ số trong phạm vi từ 2 đến 5 7" .

Để khớp các số từ 2 đến 57, sẽ dễ dàng hơn khi sử dụng biểu thức chuỗi thay vì mẫu hình cầu (hoặc cùng với đó):

for x in /foo/bar/*{2..57}; do print $x; done

Chỉnh sửa : Nhưng điều này, thật không may, sẽ không cung cấp cho bạn thứ tự từ điển của tất cả các tệp được liệt kê - chúng sẽ được nhóm theo các kết thúc số phổ biến do mở rộng vỏ.


Cảm ơn @rozcietrzewiacz! Tôi nên nghĩ về điều đó. Các tập tin của tôi có số trong đó, vì vậy trong một khoảnh khắc tôi nghĩ []là in mọi thứ theo thứ tự ..
Amelio Vazquez-Reina

Lời giải thích của bạn [2-57]là đúng, nhưng tôi không nghĩ {2..57}(đó là những gì bạn muốn nói, phải không?) Có liên quan đến những gì mà intpc muốn làm, đó là, hãy chọn các tập tin từ 2 đến 57 theo thứ tự từ điển.
Gilles 'SO- ngừng trở nên xấu xa'

Cảm ơn đã chỉnh sửa (thời gian để đi ngủ, tôi đoán). Và bạn nói đúng - Tôi đã quên phần thứ tự từ điển .
rozcietrzewiacz
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.