2013-11-02 21 views
28

Ben kabuk komut dosyaları için yeniyim. Curl kullanarak bir http isteği göndermek ve sonra düzenli ifadeler kullanarak bazı dize ayıklamak istiyorum. Örneğin, bir http yanıtından nasıl bir alan adı alabilirim? sed ile olacağınıkabuk komut dosyası. Düzenli ifadeler kullanarak dize ayıklama

#!/bin/bash 
name=$(curl google.com | grep "www\..*com") 
echo "domain name is" 
echo $name 

cevap

68

bash regular expressions kullanma:

echo ${name#http://www.} 

: Bu benzer

re="http://([^/]+)/" 
if [[ $name =~ $re ]]; then echo ${BASH_REMATCH[1]}; fi 

Düzenleme - OP sözdizimi için açıklama istedi. Regular expression syntax, burada tam olarak açıklayamadığım büyük bir konu, ancak örneği anlamak için yeterince açıklamaya çalışacağım.

re="http://([^/]+)/" 

Bu bash değişkeninde saklanan düzenli ifadedir, re - yani size girdi dizesi eşleşecek ve umarım bir alt ayıklamak için istediğini. aşağı Breaking:

  • http:// sadece bir dizedir - Normal ifade "parantez içinde herhangi karakteri eşleştirmek" demek kullanılmaktadır
  • [] Normalde köşeli parantezleri maç için giriş dizesi bu alt dize içermelidir. Yani c[ao]t hem "kedi" hem de "karyola" ile eşleşir. [] içinde ^ karakteri bu " köşeli parantez içinde olanlar dışındaki tüm karakterler maç. [^/] dışında herhangi bir karakterle eşleşir bu durumda Yani 'demek tadil etmektedir /'.
  • köşeli ayraç ifadesi yalnızca bir karakter eşleşir . bunun sonuna bir + ekleme diyor "maç 1 veya önceki alt ifadenin" geçti. Yani [^/]+ maçlar 1 veya tüm karakterlerin seti, "/" hariç.
  • alt ifadenin bir çevrede () parantez koymak daha daha sonra işlemek için bu alt ifadeyi eşleştirmekle ilgili kaydetmek istediğinizi belirtir.Eğer kullandığınız dil bunu destekliyorsa, ese yandaşları. Bash için BASH_REMATCH dizisidir.
  • Nihayet biz tam etki alanı adının sonuna kadar tüm yol eşleşen emin olmak için "/" konulu tam bir eşleşme yapmak ve aşağıdaki "/"

Sonra, giriş dizesi test etmek zorunda eşleşip eşleşmediğini görmek için düzenli ifadeye karşı. Bunu yapmak için koşullu bir yumruk kullanabilirsiniz: Bash olarak

if [[ $name =~ $re ]]; then 
    echo ${BASH_REMATCH[1]} 
fi 

, [[ ]] uzatılmış koşul testi belirtin ve =~ bash düzenli ifade operatörü içerebilir.Bu durumda $name giriş dizgisinin $re düzenli ifadesine uyup uymadığını test ederiz. bunun nedeni normal ifadenin yapımına sonra maçı, yaparsa, biz (parantez () itibaren) bir submatch sahip olacağı garanti edilir ve biz BASH_REMATCH'de dizisi kullanarak erişebilirsiniz: ait

  • Eleman 0 Bu dizi ${BASH_REMATCH[0]}, düzenli ifade tarafından eşleştirilen tüm dize olacak, yani "http://www.google.com/".
  • Bu dizinin sonraki öğeleri, alt eşlemelerin sonraki sonuçları olacaktır. Düzenli bir ifade içinde birden çok eşleşme () olabilir unutmayın - BASH_REMATCH öğeleri sırayla bunlara karşılık gelecektir. Yani bu durumda ${BASH_REMATCH[1]}, "www.google.com" ı içerecek ve bence istediğin dize.

BASH_REMATCH dizisinin içeriğinin yalnızca son kez =~ işlecinin kullanıldığı normal ifade için geçerli olduğuna dikkat edin. Yani daha düzenli ifade eşleşmeleri yapmaya devam ederseniz, bu diziden istediğiniz içeriği her seferinde kaydetmeniz gerekir.

Bu, uzun bir açıklama gibi görünebilir, ancak normal ifadelerin bazı inceliklerini gerçekten gizledim. Oldukça güçlü olabilirler ve iyi performansa inanıyorum ama normal ifade sözdizimi karmaşıktır. Ayrıca düzenli ifade uygulamaları farklıdır, bu yüzden farklı diller farklı özellikleri destekleyecektir ve sözdiziminde ince farklılıklar olabilir. Özellikle, düzenli bir ifadenin içinde karakterlerin kaçması, özellikle bu karakterlerin söz konusu dilde farklı bir anlamı olduğunda, dikenli bir konu olabilir. yerine ayrı bir satırda $re değişkeni ayarlama ve durumda bu değişkenin atıfta yerine, durumuna doğrudan düzenli ifadeyi koyabilirsiniz


Not. Ancak, bash 3.2'da, bu tür düzenli normal ifadelerin etrafındaki tırnakların gerekip gerekmediğine ilişkin kurallar değiştirildi. Düzenli ifadeyi ayrı bir değişkene koymak, bunun etrafında basit bir yoldur, böylece koşul, =~ eşleme operatörünü destekleyen tüm bash sürümlerinde beklendiği gibi çalışır.

+0

Büyük/küçük harf duyarlı olmayan bir eşleşme yapmanız veya başka bayraklar değiştirmeniz gerekiyorsa ne olur? –

5

bir yolu (örneğin öğrenme amaçlıdır). Örneğin:?

echo $name | sed -e 's?http://www\.??' 

Normalde sed düzenli ifadeler `/ tarafından sınırlandırılır', ancak kullanabilirsiniz '' '/' aradığınızdan beri. İşte başka bir bash numarası. @ DigitalTrauma'nın cevabı bana bunu önermem gerektiğini hatırlattı. (.: Işlenmesi gereken "http: //" DigitalTrauma Ayrıca hatırlattığın için kredi alır)

İlgili konular