Biasanya, bash globbing peka terhadap huruf besar-kecil:
$ echo c*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo C*
CarePackage.md ChocRippleCake.md Clips
Menggunakan tanda kurung siku tampaknya tidak mengubah ini:
$ echo [c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C]*
CarePackage.md ChocRippleCake.md Clips
Itu masih tidak mengubahnya jika tanda hubung digunakan:
$ echo [c-c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C-C]*
CarePackage.md ChocRippleCake.md Clips
Tetapi surat-surat itu diselingi:
$ echo [B-C]*
CarePackage.md casefix.pike cdless chalices.py charconv.py chocolate.pike ChocRippleCake.md circum.py clip.pike Clips cpustats.pike crop.pike cwk2txt.py
$ echo [b-c]*
beehive-anthem.txt bluray2mkv.pike branch branchcleanup.pike burdayim.pike casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
Ini menunjukkan bahwa tanda hubung menggunakan urutan lokal, "AaBbCcDd". Jadi: apakah ada cara untuk glob untuk semua file yang dimulai dengan huruf besar?
[A-Z]
mencocokkan huruf kecil dalam bash?Jawaban:
Di bash versi 4.3 dan yang lebih baru, ada opsi shopt bernama
globasciiranges
:Menurut halaman manual shopt builtin gnu :
Hasilnya kamu bisa
Gunakan
shopt -u
untuk menonaktifkan.Cara lain adalah mengubah lokal ke C. Anda dapat melakukan ini sementara menggunakan subkulit:
Anda akan mendapatkan hasil yang Anda butuhkan, dan ketika sub shell selesai, lokal shell utama Anda tetap tidak berubah menjadi apa pun sebelumnya.
Alternatif lain adalah alih-alih
[A-Z]
menggunakan ekspansi brace{A..Z}
bersama dengannullglob
opsi bash shopt.Dengan mengaktifkan
nullglob
opsi, jika suatu pola tidak cocok selama ekspansi pathname, string null dikembalikan sebagai ganti pola itu sendiri.Akibatnya yang ini akan berfungsi seperti yang diharapkan:
sumber
[[:upper:]]
karena saya benar-benar ingin hanya bagian dari alfabet, tetapi ini berfungsi.man bash
di terminal Anda dan mencari (menggunakan/
) untuk globasciiranges.LC_ALL=C printf '%s\n' [A-Z]*
bekerja untuk solusi kedua Anda - tanpa subkulit? BTW: ada salah ketik:,nullblog
tapi terlalu sedikit karakter untuk saya perbaiki.Anda dapat menulis semua huruf besar dengan baik seperti:
atau gunakan dapat menggunakan kelas karakter bernama
[:upper:]
untuk mewakili semua huruf besar di saat ini Andalocale
:Seperti yang telah Anda perhatikan, saat menggunakan rentang seperti
[B-C]
huruf besar dan kecil untuk karakter alfabet yang sama sedang diatur secara berdampingan (sesuai dengan urutan susunan huruflocale
).sumber
Termasuk karakter "tidak intuitif" dalam rentang karakter, seperti termasuk huruf kecil dalam rentang yang batas-batasnya adalah huruf besar, karena
LC_COLLATE
pengaturan lokal.LC_COLLATE
seharusnya menunjukkan urutan penyortiran, tetapi itu melakukan pekerjaan yang buruk (menyortir string lebih kompleks daripada apa yang dapat dilakukan lokal) dan Anda lebih baik tanpanya. Saya sarankan untuk menghapusLC_COLLATE
dari pengaturan lokal Anda. Jika Anda pengaturan sedangLANG
, atauLANGUAGE
, jangan lakukan itu dan mengatur hanya yang Anda perlu:LC_CTYPE
,LC_MESSAGES
,LC_TIME
.Untuk latar belakang lebih lanjut tentang lokal, lihat Apa yang harus saya atur lokal saya dan apa implikasi melakukannya? dan atur LC_ * tetapi tidak LC_ALL
Untuk mendapatkan hasil yang andal dalam skrip terlepas dari pengaturan pengguna, setel
LC_ALL=C
.sumber
Set:
Dari halaman bash man:
Jika Anda mengatur 'globasciiranges', saya tidak tahu apa yang akan terjadi pada karakter non-ascii seperti utf-8
sumber
echo [cC] * harus melakukan apa yang Anda inginkan, sama halnya [A-Za-z] *
Saya di sini karena globbing pada sistem saya baru saja berhenti menjadi case sensitif, jadi banyak skrip saya tidak lagi berfungsi sebagaimana mestinya :-(
sumber