Bir bash betiğinde desene göre dize çıkarma


17

Bash, varsayalım ki bir dize var strname:

strname="ph7go04325r"

İlk "3" karakter ve son "r" karakter arasındaki karakterleri ayıklamak strname, sonucu bir dize kaydetmek istiyorum strresult. Yukarıdaki örnekte, sonuç strresultşöyle olacaktır:

strresult="25"

Birinci "3"karakter mutlaka dizgideki 8 konumunda değildirstrname ; Benzer şekilde, en son "r"olan olup , aşağıdaki şeritlerinin iki, 11. Bu nedenle de pozisyonunda mutlaka strnamevermelidir strresult="25":

strname="ph11go04325raa"
strname="325r"
strname="rgo04325raa"

Ayrıca, strname=ph12go04330raa"vermelidir strresult="30".

Ben bash komut dosyası için yeni ve nerede böyle dize desen eşleştirme yapmaya başlamak için bilmiyorum. Önerin var mı?

Yanıtlar:


28

Bunu yapmak için bash (3.0 veya üstü) normal ifadesini kullanabilirsiniz:

if [[ $strname =~ 3(.+)r ]]; then
    strresult=${BASH_REMATCH[1]}
else
    echo "unable to parse string $strname"
fi

Bash'da, normal diziden yakalama grupları özel diziye yerleştirilir BASH_REMATCH. 0 öğesi tüm eşleşmeyi ve 1 öğesi ilk yakalama grubunun eşleşmesini içerir.


10

Standart shsözdiziminde (dolayısıyla bashherhangi bir POSIX uyumlu kabuğun herhangi bir sürümü ile çalışır ) şunları yaparsınız:

case $strname in
  (*3*r*) 
    strresult=${strname#*3}
    strresult=${strresult%r*};;
  (*)
    printf >&2 '%s\n' "Unable to parse string $strname"
esac

Ayrıca expr35 yıllık Unices üzerinde bile çalışacak eski çözüme bakın :

expr "x$strname" : 'x[^3]*3\(.*\)r'

Eski cilvesi ile exprmaç başarısız olursa sıfır olmayan bir çıkış durumu (ince) elde edilmesi, ama aynı zamanda (olduğu gibi iade dizeleri giderir eğer 0'a sıfırdan farklı çıkış durumu olsun strname=zz300rzz).


İfadenizin yanlış olduğunu, bunun sadece bash'ın eski sürümleriyle yapılabileceğini ima ettiğini düşünüyorum . Parametre genişlemesi, elbette, modern kabuklarda hala iyi bir yaklaşımdır.
kojiro

1
@kojiro, ne demek istediğini anlıyorum. İlk formülasyon Ürdün'ün cevabını takip etmekti. Cevabımı güncelledim.
Stéphane Chazelas
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.