Ini adalah pertanyaan PR:
Cocokkan semua nama file dengan 2 karakter atau lebih yang dimulai dengan huruf kecil, tetapi jangan diakhiri dengan huruf besar.
Saya tidak mengerti mengapa solusi saya tidak berfungsi.
Jadi saya mengeksekusi di bawah ini:
touch aa
touch ha
touch ah
touch hh
touch a123e
touch hX
touch Ax
ls [a-z]*[!A-Z]
Keluaran:
aa ha
Pertanyaan saya: Mengapa tidak cocok dengan "ah", "hh", atau "a123e"?
mksh
shell, tetapi tidakbash --posix
, jadi pasti ada beberapa aturan khusus untuk bash`mksh
sepertizsh
's[A-Z]
tidak cocok padaÉ
misalnya. Pertandingan ksh93[A-Z]
aktifÉ
tetapi tidak aktifh
.Jawaban:
Ini adalah masalah lokal . Di lokal Anda,
[A-Z]
perluas sesuatu seperti[AbBcZ...zZ]
(ditambah mungkin yang lain seperti karakter beraksen), karena itu[^A-Z]
sebenarnya berarti "file yang diakhiri dengana
" dalam contoh Anda (dan hanya dalam contoh Anda).Jika Anda ingin menghindari kejutan seperti itu, salah satu caranya adalah mengatur
LC_COLLATE=C
karena pemeriksaan adalah bagian dari pengaturan lokal Anda yang bertanggung jawab atas urutan penyortiran. Juga, kosongkanLC_ALL
jika sudah diatur, karena akan diutamakan.Atau, lebih baik, mungkin lebih baik tidak mengubah pengaturan lokal Anda dan menggunakan kelas yang sesuai:
[:lower:]
alih- alih[a-z]
dan[:upper:]
bukannya[A-Z]
.Atau gunakan
globasciiranges
opsi bash :sumber
LC_ALL=C ls [a-z]*[^A-Z]
hanya akan mempengaruhils
lokal, bukan lokal yang digunakan oleh shell untuk memperluas glob atau mengurai baris perintah itu.LC_xxx
agar dapat diterapkan ke glob, tetapi akan lebih disukai sehingga mendapatkan lokasi yang sama.test-鏏
misalnya karena setelah Anda mengubah charset ke yang dari lokal C,鏏
menjadi<0xe7>A
. TKI, saat mengganti LC_CTYPE, Anda mendapatkan karakter yang berbeda.é
,Á
(tapi mungkin tidakŹ
). TKI, menggunakan[A-Z]
sedikit tidak masuk akal di luar C locale.