SORU
12 Aralık 2009, CUMARTESİ


Grep bir normal ifade yakalama Grupları

sh Bu küçük komut dosyası var (Mac OS X 10.6) dosyaları bir dizi bakmak. Google bu noktada yardımcı olmak durdu:

files="*.jpg"
for f in $files
    do
        echo $f | grep -oEi '[0-9] _([a-z] )_[0-9a-z]*'
        name=$?
        echo $name
    done

Far (açıkçası, shell uzmanları için) $name sadece 0, 1 veya 2 grep dosya adı meseleyi sağlanan uygun bulursa bağlı olarak tutar.İstediğim parens içinde ([a-z] ) ve bir değişken için bu mağazaya ne yakalamak.

İstiyorummümkünse grep sadece kullanmak için. Yok Hayır, lütfen Python veya Perl, vb. Ya da bunun gibi bir şey sed – kabuk yeniyim ve *nix pürist açıdan saldırmak ister.

Ayrıca, bir olaraksüper bonus, kabuk dize bağlamak nasıl merak ediyorum? Ben yakalanan grup dize "" ad $saklanan ve dize eklemek istedim ".kanala girişi yasaklanacaktır oldu"sonuna kadar, cat $name '.jpg' alabilir miyim? jpg

Eğer zamanın varsa lütfen neler olduğunu açıklar.

CEVAP
12 Aralık 2009, CUMARTESİ


Eğer Bash kullanıyorsanız, hatta grep kullanmak zorunda değilsiniz

files="*.jpg"
regex="[0-9] _([a-z] )_[0-9a-z]*"
for f in $files
do
    [[ $f =~ $regex ]]
    name="${BASH_REMATCH[1]}"
    echo "${name}.jpg"    # concatenate strings
    name="${name}.jpg"    # same thing stored in a variable
done

Edit: daha iyi bir değişken normal ifade. Bazı desenler ise tam anlamıyla dahil işe yaramaz.

Bu Bash bu düzenli ifade maç operatörü =~ kullanır. MAÇ SONUÇLARI bir dizi $BASH_REMATCH adında kaydedilir. İlk yakalama grubu Dizini 1, 2, vs. Endeksi ikinci (varsa) depolanır. Dizin sıfır tam uyuyor.

Aradığınız şey olmayabilir çapalar olmadan, bu düzenli ifade (ve bir grep kullanarak) aşağıdaki örnekler herhangi bir maç olacağını bilmeniz gerekir:

123_abc_d4e5
xyz123_abc_d4e5
123_abc_d4e5.xyz
xyz123_abc_d4e5.xyz

İkinci ve dördüncü örnekler ortadan kaldırmak için, böyle düzenli olun:

^[0-9] _([a-z] )_[0-9a-z]*

dize gerekir diyorbaşlayınbir veya daha fazla rakam ile. Karat dize başlangıcını temsil etmektedir. Eğer normal ifade sonunda bir dolar işareti eklerseniz, bu gibi:

^[0-9] _([a-z] )_[0-9a-z]*$

sonra üçüncü örnekte de nokta düzenli karakterler arasında olmadığından ortadan kalkacak ve dolar işareti dize sonunu temsil ediyor. Dördüncü örnek de bu maç başarısız olduğunu unutmayın.

Eğer grep \K operatör eklendiğinde 2.5 veya daha sonra, sanırım, () GNU varsa:

name=$(echo "$f" | grep -Po '(?i)[0-9] _\K[a-z] (?=_[0-9a-z]*)').jpg

\K operatör (değişken-uzunluk-arkasına bak) maç için önceki desen olur, ama sonuç olarak maçı dahil değil. -Uzunluğuna eşittir (?<=) - desen kapatma parantezi önce dahil olur. Eğer nicelik uzunlukları (, *, {2,4}**28 örneğin). farklı dizeleri maç olabilir eğer \K kullanmalısınız

(?=) operatör, sabit veya değişken uzunlukta desenleriyle eşleşir ve denir "ileriye bak". Ayrıca, sonuç olarak eşleşen dize içermez.

Maçın büyük / küçük harf duyarlı hale getirmek için, (?i) operatörü kullanılır. Konumu önemli yani onu takip desenler etkiler.

Normal ifade düzeltilmiş dosya diğer karakterler olup olmamasına bağlı olarak gerekebilir. Bu durumda, alt yakalanan aynı zamanda bir dizeyi bitiştirmek için bir örnek göstereyim unutmayın.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Adam Outler

    Adam Outler

    19 EKİM 2006
  • MagmaRhino

    MagmaRhino

    16 Temmuz 2011
  • TomSka

    TomSka

    30 Mayıs 2006