[A-Z]
trong bash
trận đấu tất cả các đối chiếu các yếu tố (nhân vật nhưng gọi cũng được chuỗi các ký tự như Dsz
trong miền địa phương Hungary) mà loại sau A
và sắp xếp trước Z
. Ở địa phương của bạn, c
có thể sắp xếp ở giữa B và C.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | sort
a
A
á
b
B
c
C
Ç
z
Z
Ẑ
Vì vậy, c
hoặc z
sẽ được kết hợp bởi [A-Z]
, nhưng không Ẑ
hoặc a
.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ |
pipe> bash -c 'while IFS= read -r x; do case $x in [A-Z]) echo "$x"; esac; done'
A
á
b
B
c
C
Ç
z
Z
Trong miền địa phương C, thứ tự sẽ là:
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | LC_COLLATE=C sort
A
B
C
Z
a
b
c
z
Ç
á
Ẑ
Vì vậy, [A-Z]
sẽ phù hợp với A
, B
, C
, Z
, nhưng không phải Ç
mà vẫn không Ẑ
.
Nếu bạn muốn khớp với chữ in hoa (trong bất kỳ tập lệnh nào), bạn có thể sử dụng [[:upper:]]
thay thế. Không có cách dựng sẵn bash
để chỉ khớp các chữ cái in hoa trong tập lệnh Latin (ngoại trừ bằng cách liệt kê chúng riêng lẻ).
Nếu bạn muốn để phù hợp với A
với Z
tiếng Anh chữ không dấu, bạn có thể sử dụng [A-Z]
hay [[:upper:]]
nhưng trong C
miền địa phương (giả sử dữ liệu không được mã hóa trong các bộ ký tự như BIG5 hoặc GB18030 trong đó có nhiều nhân vật có mã hóa chứa mã hóa của những chữ cái) hoặc danh sách chúng riêng lẻ ( [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
).
Lưu ý rằng có một số biến thể giữa các vỏ.
Đối với zsh
, bash -O globasciiranges
(tùy chọn có tên lạ được giới thiệu trong bash-4.3) schily-sh
và yash
, [A-Z]
khớp với các ký tự có điểm mã nằm giữa điểm đó A
và điểm đó Z
, do đó sẽ tương đương với hành vi của bash
ngôn ngữ C.
Đối với tro, mksh và vỏ cổ, giống như zsh
trên nhưng giới hạn ở các bộ ký tự byte đơn. Nghĩa là, trong một ngôn ngữ UTF-8 chẳng hạn, [É-Ź]
sẽ không khớp Ó
, nhưng vì đó [<c3><89>-<c5><b9>]
, nó sẽ khớp với các giá trị byte 0x89 đến 0xc5!
ksh93
hành xử như bash
ngoại trừ việc nó xử lý như các trường hợp đặc biệt có phạm vi cả hai bắt đầu bằng chữ in thường hoặc chữ in hoa. Trong trường hợp đó, nó chỉ khớp với các phần tử đối chiếu sắp xếp giữa các phần cuối đó, nhưng đó là (hoặc ký tự đầu tiên của chúng cho các phần tử đối chiếu nhiều ký tự) cũng viết thường (hoặc viết hoa tương ứng). Vì vậy, [A-Z]
sẽ có kết quả khớp É
, nhưng không e
giống như e
sắp xếp giữa A
và Z
nhưng không phải là chữ hoa A
và Z
.
Đối với fnmatch()
các mẫu (như trong find -name '[A-Z]'
) hoặc các biểu thức chính quy của hệ thống (như trong grep '[A-Z]'
), nó phụ thuộc vào hệ thống và miền địa phương. Ví dụ, trên một hệ thống GNU đây, [A-Z]
không phù hợp trên x
trong en_GB.UTF-8
miền địa phương, nhưng nó trong th_TH.UTF-8
một. Tôi không rõ thông tin mà nó sử dụng để xác định thông tin đó là gì, nhưng rõ ràng nó dựa trên bảng tra cứu có nguồn gốc từ dữ liệu bản địa LC_COLLATE ).
Tất cả các hành vi đều được POSIX cho phép vì POSIX để lại hành vi của các phạm vi không xác định ở các địa điểm khác ngoài miền C. Bây giờ chúng ta có thể tranh luận về lợi ích của từng phương pháp.
bash
Cách tiếp cận có nhiều ý nghĩa như với [C-G]
, chúng tôi muốn các nhân vật ở giữa C
và G
. Và sử dụng thứ tự sắp xếp của người dùng cho những gì xác định những gì ở giữa là cách tiếp cận hợp lý nhất.
Bây giờ, vấn đề là nó phá vỡ sự mong đợi của rất nhiều người, đặc biệt là những người đã quen với hành vi truyền thống của tiền Unicode, thậm chí cả những ngày tiền quốc tế hóa. Trong khi từ một người dùng bình thường, nó có ý nghĩa may mà [C-I]
bao gồm h
như các h
chữ cái là giữa C
và I
và [A-g]
không bao gồm Z
, đó là một vấn đề khác nhau cho những người đã bị xử lý ASCII chỉ trong nhiều thập kỷ.
bash
Hành vi đó cũng khác với [A-Z]
phạm vi khớp trong các công cụ GNU khác như trong các biểu thức chính quy GNU (như trong grep
/ sed
...) hoặc fnmatch()
như trong find -name
.
Điều đó cũng có nghĩa là những gì [A-Z]
phù hợp sẽ thay đổi theo môi trường, với HĐH và với phiên bản HĐH. Thực tế [A-Z]
phù hợp với Á nhưng không cũng không tối ưu.
Đối với zsh
/ yash
, chúng tôi sử dụng một thứ tự sắp xếp khác nhau. Thay vì dựa vào khái niệm về thứ tự ký tự của người dùng, chúng tôi sử dụng các giá trị mã điểm ký tự. Điều đó có lợi ích là dễ hiểu, nhưng từ quan điểm thực tế của một số ít, bên ngoài ASCII, nó không hữu ích lắm. [A-Z]
khớp với 26 chữ cái in hoa-tiếng Anh, [0-9]
khớp với các chữ số thập phân. Có những điểm mã trong Unicode tuân theo thứ tự của một số bảng chữ cái nhưng không được khái quát hóa và không thể khái quát hóa vì dù sao những người khác nhau sử dụng cùng một tập lệnh không nhất thiết phải đồng ý về thứ tự các chữ cái.
Đối với shell và mksh truyền thống, dấu gạch ngang, nó đã bị hỏng (hiện tại hầu hết mọi người sử dụng các ký tự nhiều byte), nhưng chủ yếu là vì họ chưa có hỗ trợ nhiều byte. Thêm hỗ trợ nhiều byte cho shell như bash
và zsh
đã là một nỗ lực rất lớn và vẫn đang tiếp tục. yash
(một vỏ tiếng Nhật) ban đầu được thiết kế với sự hỗ trợ nhiều byte ngay từ đầu.
Cách tiếp cận của ksh93 có lợi ích là phù hợp với các biểu thức chính quy hoặc fnmatch () (hoặc ít nhất là xuất hiện ít nhất trên các hệ thống GNU). Ở đó, nó không phá vỡ kỳ vọng của một số người vì [A-Z]
không bao gồm các chữ cái viết thường, [A-Z]
bao gồm É
(và Á, nhưng không phải). Nó không phù hợp với sort
hoặc nói chung là strcoll()
trật tự.
locale
đầu ra? Tôi không thể sao chép điều này (touch foo; echo [A-Z]*
xuất ra mẫu chữ, không phải "foo", trong một thư mục trống khác).