[A-Z]
di bash
cocokkan semua elemen penyusun (karakter tetapi panggilan juga menjadi urutan karakter seperti Dsz
di lokal Hongaria) yang mengurutkan setelah A
dan mengurutkan sebelumnya Z
. Di tempat Anda, c
mungkin di antara B dan C.
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | sort
a
A
á
b
B
c
C
Ç
z
Z
Ẑ
Jadi c
atau z
akan dicocokkan dengan [A-Z]
, tetapi tidak Ẑ
atau 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
Di C locale, urutannya adalah:
$ printf '%s\n' A a á b B c C Ç z Z Ẑ | LC_COLLATE=C sort
A
B
C
Z
a
b
c
z
Ç
á
Ẑ
Jadi [A-Z]
akan cocok A
, B
, C
, Z
, tapi tidak Ç
dan masih tidak Ẑ
.
Jika Anda ingin mencocokkan huruf besar (dalam skrip apa pun), Anda dapat menggunakannya [[:upper:]]
. Tidak ada jalan masuk bash
untuk hanya mencocokkan huruf besar dalam skrip latin (kecuali dengan mendaftar secara individual).
Jika Anda ingin mencocokkan huruf A
ke Z
bahasa Inggris tanpa diakritik, Anda dapat menggunakan [A-Z]
atau [[:upper:]]
tetapi di C
lokal (dengan asumsi data tidak dikodekan dalam set karakter seperti BIG5 atau GB18030 yang memiliki beberapa karakter yang pengkodeannya berisi pengkodean surat-surat itu) atau daftar secara individual ( [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
).
Perhatikan bahwa ada beberapa variasi antara cangkang.
Untuk zsh
, bash -O globasciiranges
(opsi yang dinamai aneh diperkenalkan di bash-4.3), schily-sh
dan yash
, [A-Z]
cocok dengan karakter yang titik kodenya antara A
dan dari Z
, jadi akan sama dengan perilaku bash
di lokal C.
Untuk abu, mksh dan cangkang kuno, sama seperti di zsh
atas tetapi terbatas pada rangkaian byte tunggal. Yaitu, di lokal UTF-8 misalnya, [É-Ź]
tidak akan cocok Ó
, tetapi karena itu [<c3><89>-<c5><b9>]
, itu akan cocok dengan nilai byte 0x89 hingga 0xc5!
ksh93
berperilaku seperti bash
kecuali bahwa itu memperlakukan rentang kasus khusus yang ujungnya dimulai dengan huruf kecil atau huruf besar. Dalam hal ini, itu hanya cocok pada elemen penyusun yang mengurutkan antara kedua ujungnya, tetapi itu adalah (atau karakter pertama mereka untuk elemen penyusun multi-karakter) juga huruf kecil (atau masing-masing huruf besar). Jadi [A-Z]
akan cocok É
, tetapi tidak pada e
seperti e
halnya antara A
dan Z
tetapi tidak huruf besar seperti A
dan Z
.
Untuk fnmatch()
pola (seperti dalam find -name '[A-Z]'
) atau ekspresi reguler sistem (seperti dalam grep '[A-Z]'
), itu tergantung pada sistem dan lokal. Sebagai contoh, pada sistem GNU di sini, [A-Z]
tidak cocok x
di en_GB.UTF-8
lokal, tetapi itu cocok di th_TH.UTF-8
satu. Tidak jelas bagi saya informasi apa yang digunakannya untuk menentukan hal itu, tetapi tampaknya berdasarkan tabel pencarian yang berasal dari data lokal LC_COLLATE ).
Semua perilaku diizinkan oleh POSIX karena POSIX membiarkan perilaku rentang tidak ditentukan di lokal selain dari C locale. Sekarang kita dapat berdebat tentang manfaat dari setiap pendekatan.
bash
Pendekatan banyak masuk akal dengan [C-G]
, kami ingin karakter di antara C
dan G
. Dan menggunakan urutan pengguna untuk menentukan apa yang ada di antara keduanya adalah pendekatan yang paling logis.
Sekarang, masalahnya adalah itu menghancurkan harapan banyak orang, terutama orang-orang yang terbiasa dengan perilaku tradisional pra-Unicode, bahkan sebelum hari internasionalisasi. Sementara dari pengguna normal, masuk akal jika [C-I]
menyertakan h
karena h
surat itu antara C
dan I
dan yang [A-g]
tidak termasuk Z
, itu masalah yang berbeda bagi orang-orang yang berurusan dengan ASCII hanya selama beberapa dekade.
Itu bash
perilaku juga berbeda dari [A-Z]
pencocokan berbagai dalam alat GNU lain seperti di GNU ekspresi reguler (seperti dalam grep
/ sed
...) atau fnmatch()
seperti dalam find -name
.
Ini juga berarti bahwa apa yang [A-Z]
cocok bervariasi dengan lingkungan, dengan OS dan dengan versi OS. Fakta yang [A-Z]
cocok dengan Á tetapi tidak Ź juga tidak optimal.
Untuk zsh
/ yash
, kami menggunakan urutan penyortiran yang berbeda. Alih-alih mengandalkan gagasan pengguna tentang urutan karakter, kami menggunakan nilai kode titik karakter. Itu memiliki manfaat karena mudah dipahami, tetapi dari sudut pandang praktis, di luar ASCII, itu tidak terlalu berguna. [A-Z]
cocok dengan 26 huruf besar Inggris-Inggris, [0-9]
cocok dengan angka desimal. Ada poin kode di Unicode yang mengikuti urutan beberapa huruf tetapi itu tidak digeneralisasi dan tidak dapat digeneralisasi karena orang yang berbeda menggunakan skrip yang sama tidak harus menyetujui urutan huruf.
Untuk shells tradisional dan mksh, dash, itu rusak (sekarang kebanyakan orang menggunakan karakter multi-byte), tetapi terutama karena mereka belum memiliki dukungan multi-byte. Menambahkan dukungan multi-byte ke shell like bash
dan zsh
telah menjadi upaya besar dan masih berlangsung. yash
(shell Jepang) pada awalnya dirancang dengan dukungan multi-byte sejak awal.
Pendekatan ksh93 bermanfaat untuk konsisten dengan ekspresi reguler atau fnmatch sistem () (atau setidaknya tampak setidaknya pada sistem GNU). Di sana, itu tidak melanggar harapan beberapa orang karena [A-Z]
tidak termasuk huruf kecil, [A-Z]
termasuk É
(dan Á, tetapi tidak Ź). Itu tidak konsisten dengan sort
atau umumnya strcoll()
memesan.
locale
output? Saya tidak dapat mereproduksi ini (touch foo; echo [A-Z]*
menampilkan pola literal, bukan "foo", di direktori yang kosong).