[Az] yıldız işareti neden sayılarla eşleşiyor?


13

Geçerli yolda 3 dizin var.

$ls
a_0db_data  a_clean_0db_data  a_clean_data
$ls a_*_data
a_0db_data:

a_clean_0db_data:

a_clean_data:

$ls a_[a-z]*_data
a_clean_0db_data:

a_clean_data:

Son ls komutunun sadece eşleşmesini bekledim a_clean_data. Neden onu içerenle de eşleşti 0?

bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)

2
Düzenli ifade ile glob arasındaki fark hakkında daha fazla bilgi için bu soruya bakın .
terdon

4
Peki a_*_databu dosyalardan herhangi biriyle eşleşen gerçeği sizi şaşırtmadı mı?
Cthulhu

@Cthulhu beni yakaladın!
user13107

Yanıtlar:


29

[a-z]Parça numarası ile eşleşen ne değildir; bu *. Kabuk globbing ve düzenli ifadeler kafa karıştırıcı olabilir .

Araçlar gibi grep(regexes çeşitli tatlar kabul temel varsayılan olarak -E, genişletilmiş için -Piçin Perl regex )

Örn ( -vmaçı tersine çevirir)

$ ls a_[a-z]*_data | grep -v "[0-9]"
a_clean_data

Bir bash regex'i kullanmak istiyorsanız, değişkenin $refbir tam sayı olup olmadığını test etme konusunda bir örnek :

re='^[0-9]+$'
if ! [[ $ref =~ $re ]] ; then
  echo "error"
fi

O zaman bash regex nasıl kullanılır? (bkz. tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_01.html )
user13107


21

Sorun şu: neden a_[a-z]*_datauyuyor a_clean_0db_data?

Bu dört bölüme ayrılabilir :

  • a_eşleşmeye a_clean_0db_databırakarak başlangıcıyla clean_0db_dataeşleşir

  • [a-z]eşleşecek şekilde bırakarak aralıktaki a-z(ör. c) herhangi bir karakterle lean_0db_dataeşleşir

  • * herhangi bir sayıda karakterle eşleşir, ör. lean_0db

  • _data sondaki ile eşleşir _data

Normal ifadelerde, a..z aralığında herhangi bir sayıda karakter (sıfır dahil)[a-z]* anlamına gelir , ancak normal ifadelerle değil, kabuk globbing ile uğraşıyorsunuz.

Düzenli ifadeler istiyorsanız, birkaç finduygulamanın bunun için bir -regexönemi vardır:

find . -maxdepth 1 -regex "^.*/a_[a-z]*_data$"

-maxdepthEğer. İçindedir klasöre arama-sonuçlarını sınırlandırmak için sadece burada düzenli ifade ile eşleşen tüm dosya adını nedenle ben eklemiş ^.*/yol-bölümünü maç için


11

*Kabuk desenlerinde 0 veya daha fazla karakterle eşleşir. Önceki atomun 0 veya daha fazlası* anlamına gelen normal ifade operatörü ile karıştırılmamalıdır .

*Temel kabuk modellerinde normal ifade eşdeğeri yoktur . Bununla birlikte, çeşitli mermilerin bunun için uzantıları vardır.

  • kshvardır *(something):

    ls a_*([a-z])_data
  • Eğer aynı olabilir bashile shopt -s extglobya zshsahip setopt kshglob:

    shopt -s extglob
    ls a_*([a-z])_data
    
  • In zshile extendedglobetkin, #regexp eşdeğerdir *:

    setopt extendedglob
    ls a_[a-z]#_data
    
  • Son sürümlerinde, ksh93globlarda düzenli ifadeler de kullanabilirsiniz. Burada genişletilmiş düzenli ifadelerle:

    ls ~(E:a_[a-z]*_data)

[a-z]Geçerli yerel ayara bağlı olarak farklı şeylerle eşleştiğini unutmayın . Genellikle , yerel ayardaki yalnızca 26 aile zlatin arasındaki aksanlı harflerle eşleşir C. Diğer yerlerde, genellikle daha fazla eşleşir ve her zaman mantıklı değildir. Yerel ayarınızdaki bir harfi eşleştirmek için tercih edebilirsiniz [[:alpha:]].


[a-z]C yerel ayarında eşleşen 26 harften daha fazla eşleşen bir örnek verebilir misiniz ? Buna en son baktığımda hatırladığım şey, Unix varyantlarında pratik olarak kullanılan tüm kodlamaların temel olarak ISO-646'ya sahip olmasıydı (daha sonra farklı bir şekilde kullanıldığında üst 128 kodları, doğrudan ISO-8859-X gibi kodlamalardaki karakterler için UTF-8 veya EUC ailesi gibi kodlamalar). AIX bile EBCDIC yerellerine sahip değildi (en azından benim için mümkün olduğu kadar). POSIX / UNIX standartlarının talep edip etmediğini bulmaya çalıştığımı hatırlıyorum, ancak sonucu hatırlamıyorum.
AProgrammer

1
@AProgrammer, kodlamadan bağımsız, sıralama düzenine (LC_COLLATE) dayalı. [a-z]genellikle, kodlamadaki kod noktasının a ve z ile aynı olup olmadığına bakılmaksızın, karakter kümesinin bunlara sahip olduğu yerel ayarları içerir éveya ízorunlu źdeğildir. Yalnızca C yerel ayarı, kod noktası değerine dayalı bir sıralama düzenini garanti eder. Daha fazla ayrıntı için bu diğer cevaba bakınız.
Stéphane Chazelas

Tamam, kaçırdığım şey, aralığın geçerli harmanlama sırasına göre yorumlanmasıydı.
AProgrammer
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.