Köşeli ayraç globbinginde büyük / küçük harfe duyarlılık


10

Normalde bash globbing büyük / küçük harfe duyarlıdır:

$ 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

Köşeli parantez kullanmak bunu değiştirmiyor gibi görünüyor:

$ 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

Kısa çizgi kullanılıyorsa hala değiştirmez:

$ 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

Ancak harfler serpiştirilmiş:

$ 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

Bu, tire işaretinin "AaBbCcDd" yerel ayarını kullandığını gösterir. Öyleyse: büyük harfle başlayan tüm dosyaları temizlemenin bir yolu var mı?


3
Ayrıca [AZ] 'z' hariç her küçük harfe uyuyor!
PJTraill

Yanıtlar:


12

Bash 4.3 ve sonraki sürümlerinde şu adla bir shopt seçeneği vardır globasciiranges:

Göre gnu adam sayfalarında yerleşik shopt :

globasciiranges Ayarlandıysa
, desen eşleştirme parantez ifadelerinde kullanılan aralık ifadeleri (bkz. Desen Eşleme), karşılaştırmalar yapılırken geleneksel C yerel ayarındaymış gibi davranır. Yani, geçerli yerel ayarın harmanlama sırası dikkate alınmaz, bu nedenle 'b', 'A' ve 'B' arasında harmanlanmaz ve büyük ve küçük harf ASCII karakterleri birlikte harmanlanır.

Sonuç olarak

$ shopt -s globasciiranges 
$ echo [A-Z]*

shopt -uDevre dışı bırakmak için kullanın .

Başka bir yol, yerel ayarı C olarak değiştirmektir. Bunu bir alt kabuk kullanarak geçici olarak yapabilirsiniz:

$ ( LC_ALL=C ; printf '%s\n' [A-Z]*; )

İhtiyacınız olan sonuçları alacaksınız ve alt kabuk bittiğinde, ana kabuğunuzun yerel ayarı daha öncekiyle değişmeden kalacak.

Başka bir alternatif ise [A-Z]küme genişletmesini bash shopt seçeneğiyle {A..Z}birlikte kullanmaktır nullglob.

nullglobSeçeneği etkinleştirerek, yol adı genişletmesi sırasında bir desen eşleşmezse, desenin kendisi yerine bir boş dize döndürülür.
Sonuç olarak bu beklendiği gibi çalışacaktır:

$ shopt -s nullglob;printf '%s\n' {A..Z}*

2
Mükemmel teşekkürler. Kullanamıyorum [[:upper:]]çünkü aslında alfabenin bir kısmını istiyorum, ama bu işe yarıyor.
rosuav

1
@rosuav Hoşgeldiniz. Alt kabuk alternatifini de kontrol edin.
George Vasiliou

“Etkinleştirilmişse C yerel ayarına eşitse” - bu, globbing için kullanılan yerel ayarı etkilediği anlamına mı geliyor? (Bir referans bağlantısı yardımcı olabilirdi - bulabildiğim en iyi şey gnu.org/software/bash/manual/html_node/Pattern-Matching.html , ancak tüm kabuk seçeneklerinin bir listesini tercih ederdim, ancak globasciiranges eksik dan gnu.org/software/bash/manual/html_node/... ; ayrıca sorunun unix.stackexchange.com/questions/227070/... tutamaklar bu konunun kapsamlı olarak) Ayrıca sürüm 4.3 den..
PJTraill

@PjTrail Düzenlememi tüm çekim seçeneklerine referans bağlantısı ile görün. Ayrıca man bashterminalinizde çalışabilir ve /globasciiranges için arama (kullanarak ) yapabilirsiniz.
George Vasiliou

Olmaz LC_ALL=C printf '%s\n' [A-Z]*ikinci çözümü için çalışmak - bir kabuktaki olmadan? BTW: bir yazım hatası var: nullblogama düzeltmem için çok az karakter var.
Joe

5

Tüm büyük harfleri aşağıdaki gibi iyi yazabilirsiniz:

[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*

veya kullan, [:upper:]geçerli durumunuzdaki tüm büyük harfleri temsil etmek için adlandırılmış karakter sınıfını kullanabilir locale:

[[:upper:]]*

Fark ettiğiniz gibi [B-C], aynı alfabetik karakter için büyük ve küçük harf gibi bir aralığı kullanırken bitişik olarak düzenlenir ( locale.


3

Sınırları büyük harf olan bir aralıktaki küçük harfler de dahil olmak üzere, karakter aralıklarına “sezgisel olmayan” karakterler eklemek LC_COLLATEyerel ayardan kaynaklanmaktadır. LC_COLLATEsıralama düzenini belirtmesi gerekiyordu, ancak kötü bir iş yapıyor (dizeleri sıralama, yerel ayarların yapabileceğinden daha karmaşık) ve onsuz daha iyi durumdasınız. LC_COLLATEYerel ayarlarınızdan kaldırmanızı öneririm . Konum ayarı ise LANG, ya LANGUAGE, sen gerek olmadığına işaret yapmak ve sadece onlar set yoktur: LC_CTYPE, LC_MESSAGES, LC_TIME.

Yerel ayarlarla ilgili daha fazla bilgi için Yerel ayarımı neye ayarlamalıyım ve bunu yapmanın sonuçları nelerdir? Konusuna bakın. ve LC_ * ayarlasın ama LC_ALL değil

Kullanıcının ayarlarından bağımsız olarak bir komut dosyasında güvenilir sonuçlar elde etmek için ayarlayın LC_ALL=C.


0

Ayarlamak:

shopt -u nocaseglob

Bash man sayfasından:

>     nocaseglob
>         If  set,  bash matches filenames in a case-insensitive
>         fashion when performing pathname expansion (see Pathname
>          Expansion above).

'Globasciiranges'i ayarlarsanız utf-8 gibi ascii olmayan karakterlere ne olacağını bilmiyorum


0

echo [cC] * istediğinizi yapmalı, benzer şekilde [A-Za-z] *

Buradayım çünkü sistemimdeki globbing büyük / küçük harfe duyarlı olmayı bıraktı , bu yüzden komut dosyalarımın birçoğu olması gerektiği gibi çalışmıyor :-(


Gördüğümün tam tersi. Ancak öneriler için diğer yanıtları kontrol edin.
rosuav
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.