Sự khác biệt giữa {1,2,3} và {1..3}


17

Có sự khác biệt giữa các trình tự {1,2,3}{1..3}?

Ví dụ: nếu tôi có một số tập tin

file.1
file.2
file.3

và tôi muốn catchúng cùng sử dụng có an toàn cat file.{1..3} > filekhông?

Những gì tôi biết là cat file.*>file có thể gây ra vấn đề bởi vì trình bao có thể mở rộng các tệp theo cách ngẫu nhiên (tôi nghĩ điều này phụ thuộc vào các nút, phải không?)


1
sử dụngcat file.[123] >file
mikeerv

3
Thứ tự mở rộng file.*không phụ thuộc vào các nút. Nó luôn sắp xếp chúng theo từ vựng, có thể phụ thuộc vào cài đặt định vị của bạn.
Barmar

1
"phụ thuộc vào các nút" nghe giống như một giai đoạn từ một trong những cảnh "máy tính" hình sự được nghiên cứu tốt hơn.
Alec Teal

1
@mikeerv, tôi tin rằng tôi đã nhận được nó. Nó là một vỏ toàn cầu, vì vậy nó chỉ mở rộng ra các tệp thực sự tồn tại, phải không? Vs file.{1..3}mở rộng ra cả ba dù chúng có tồn tại hay không.
tự đại diện

1
@Wildcard - đúng, miễn là có ít nhất một cái tồn tại, đó là. Nếu không, nó không mở rộng và catlỗi với file.[123] not foundhoặc một cái gì đó rất hữu ích.
mikeerv 15/03/2016

Câu trả lời:


18

{1..3}{1,2,3}tạo ra kết quả tương tự, nhưng với cách khác nhau.

Nói chung, {n1..n2}(mà đến đầu tiên từ zsh, bashkshsao chép nó sau này), nơi n1n2được số nguyên sản xuất tất cả các số giữa n1n2. Trong khi {x,y,z}sản xuất ba nhân vật x,yz.

Trong trường hợp của bạn, bạn an toàn khi sử dụng cat file.{1..3} > file

Bây giờ, trong trường hợp cat file.*>file, bạn đã sử dụng shell shellbing , tạo ra tất cả tên tệp bắt đầu file.và kết quả sẽ được sắp xếp dựa trên thứ tự đối chiếu trong miền địa phương hiện tại.

Bạn vẫn an toàn, nhưng không còn nữa khi bạn có hơn 10 tệp. {1..10}sẽ cung cấp cho bạn 1 2 3 4 5 6 7 8 9 10. Trong khi với Globing, bạn sẽ nhận được1 10 2 3 4 5 6 7 8 9


8

Sự khác biệt là một là một danh sách và một chuỗi khác. {1,2,3}mở rộng tới ba yếu tố cụ thể, 1, 2, và 3. {1..3}mở rộng đến danh sách các số từ một đến ba. Trong trường hợp cụ thể này, chúng giống nhau và bạn có thể sử dụng một trong hai. file.*sẽ mở rộng ra tất cả các tệp và thư mục trong thư mục hiện tại có tên bắt đầu bằng file.. Nếu bạn chỉ có file.1, file.2file.3điều đó cũng tương đương với hai người kia.

Về vấn đề gây ra nó, tôi không hiểu tại sao. Bạn có thể nghĩ về

$ cat file.* > file.txt
cat: file.txt: input file is output file

Tuy nhiên, đó là một vấn đề hoàn toàn khác. Vấn đề duy nhất khác mà tôi có thể nghĩ đến là shell của bạn có thể không liệt kê các tệp theo đúng thứ tự. Ví dụ:

$ touch file1 file11 file2
$ echo file*
file1 file11 file2

Để giải quyết điều đó, bạn có thể sử dụng zshthay vì bash(xem tại đây để biết chi tiết):

% echo f*(n)
file1 file2 file11

Nói chung, ba cách tiếp cận không giống nhau. Nó phụ thuộc vào những gì bạn muốn làm. Trong những trường hợp mà ba trả về cùng một đầu ra sau đó, vâng, bạn có thể sử dụng bất kỳ trong số chúng. Nó không có Gì Thay đổi. Tất cả các mở rộng này được thực hiện bởi shell và xảy ra trước khi chúng được truyền cho bất kỳ lệnh nào sử dụng chúng.


sẽ không có vấn đề gì *nếu tôi có nhiều hơn hoặc bằng 10 tệp, nếu tôi phụ thuộc vào thứ tự đúng?
syss

1
@syss không. Sẽ là một vấn đề nếu bạn có nhiều hơn ARG_MAXcác tệp nhưng đó sẽ là cách, hơn 10.
terdon

1
@terdon Anh ấy hỏi liệu chúng có xuất hiện theo thứ tự số không (nghĩa là không phải "1, 10, 2"), chứ không phải chúng sẽ tràn mảng mảng đối số.
Random832

3
@terdon Tôi nghĩ @syss đúng là đầu ra của cat *không được xác định rõ. Đầu ra phụ thuộc vào vỏ và môi trường. Xem bình luận của Sebastian .
Marco

Không thêm .txtgiải quyết vấn đề với file.*?
Ismael Miguel

6

Chúng giống nhau, nhưng nó phụ thuộc vào phiên bản bash bạn đã cài đặt nếu chúng có sẵn.

Từ này trang:

{xxx,yyy,zzz,...} probably in all bash versions

{a..z} introduced in bash 3

{<START>..<END>..<INCR>} new in bash 4
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.