Yapmanın daha iyi bir yolu “echo $ x | sed… ”ve“ echo $ x | grep… ”


14

Bunu genellikle senaryolarda bulurum (ve itiraf etmeliyim, kendim yazmalıyım):

a=$(echo "$x" | sed "s/foo/bar/")

veya

if echo "$x" | grep -q foo
then
    ...
fi

Bazı normal ifadeleri dahil etmek için "foo" düşünün.

Ben olması gerektiğini hissediyorum - ve büyük olasılıkla olduğunu - ifade bu iki komut ve bir boruyu içerir ama biraz daha kompakt ifadeye şeyi sarar gelmez biri için daha iyi bir yol.

Sadece bulamıyorum. Bir kimse?


Bu ifade, cehalet (alternatifleri bilmemek) ve sürdürülebilirlik (alternatifleri bilmek, ancak bunu daha basit olarak seçilmesi) bir kombinasyonu nedeniyle sık sık kullanılmasını bekliyorum. Bir bakışta örneklerinizin ne yaptığını söyleyebilirim, ancak grawity ve Dan McG'ın cevaplarındaki alternatifleri anlamak için bir kabuk referansına ihtiyacım var.
quack quixote

3
Bu arada, komut ikamesi yapmak için tercih edilen yöntem $()backticks yerine yöntemdir .
sonraki duyuruya kadar duraklatıldı.

2
Boşlukların korunması için genişletmeleri belirtmek de iyi bir fikirdir: a="$(echo "$x" | sed "s/foo/bar/")"ve if echo "$x" | grep foo; ….
Chris Johnsen

$ () Ve `` hakkında iyi yorumlar. Görüyorum ki bash becerilerim o kadar da iyi değil.
DevSolar

Yanıtlar:


12

Belirli bir kabuk kabul etmedikçe, bunu "alete boru yankısı" (veya sadece ifade gibi bir "aletin" ) yönteminden daha iyi bir yol yoktur ; geleneksel Bourne kabuğu ve / veya POSIX kabuğu ile gerçekten güvenebileceğiniz tek şey . Başka mermileri düşünürseniz, başka yerleşik olasılıklar da vardır.

ksh var

  • Ekstra desenler ?(pattern-list), *(pattern-list), {n}(pattern-list), {n,m}(pattern-list), @(pattern-list), !(pattern-list);
  • %P Printf belirteci (ve bir model halinde bir genişletilmiş normal ifade dönüştürmek %Rdesene genişletilmiş düzenli ekspresyonu);
  • expr == patternkoşulu [[ expr ]]testleri;
  • ${param/pattern/replacement}Parametre genişlemesi.

bash var

  • extglobekstra desen en etkinleştirme seçeneği ksh (hayır {n}ve {n,m});
  • expr == pattern(koşul [[ expr ]]testleri için);
  • ${param/pattern/replacement}Parametre genişlemesi;
  • (yeni sürümlerde) genişletilmiş düzenli ifadelerle eşleşebilecek expr =~ extregexpdurum ( [[ expr ]]testlerde)
    • parantez içine alınmış alt ifadeler ve BASH_REMATCHparametre ile sed- stili değiştirmeler yapılabilir.

zsh var

  • EXTENDED_GLOBseçeneği ile kendi genişletilmiş desenleri ;
  • KSH_GLOBseçeneği ile ksh benzeri genişletilmiş desenler ;
  • expr == pattern(koşul [[ expr ]]testleri için);
  • ${pattern/pattern/replacement}Parametre genişlemesi;
  • expr =~ extregexp(koşul [[ expr ]]genişletilmiş düzenli ifadeler karşı eşleşebilir testler),
    • RE_MATCH_PCRE seçeneği ayarlanmışsa düz genişletilmiş normal ifadeler yerine PCRE kullanabilir ,
    • parantez altifadelerle ile MATCHparametre ve matchparametre (ya da BASH_REMATCHbirlikte BASH_REMATCHisteğe bağlı grubu), sed tarzı değiştirmeler yapılabilir;
  • zsh/pcreModül, bu teklif pcre_compile, pcre_studyve pcre_matchkomutları ve -pcre-match deney (koşul [[ expr ]]testleri için);
  • zsh/regexsunan modül -regex-match testi (in durumu [[ expr ]]testler).

Vay. İstediği kadar eksiksiz. Kesinlikle bir kazanan.
DevSolar

6

Sed hattını değiştirmek için aşağıdaki gibi bir şey yapın

${a/foo/bar} veya ${a//foo/bar}

İlk formda, yalnızca ilk örnek değiştirilir. İkinci form küresel bir arama ve değiştirme işlemidir.

Sizin durumunuzda,

Onun yerine:

if echo $x | grep foo
then
    ...
fi

Şunları kullanmayı düşünün:

if [ $x =~ foo ]
then
    ...
fi

fooDüzenli bir ifade nerede .


Bu hangi kabuklarda çalışır?
Peltier

1
if [ $x =~ foo ]burada bir hata mesajı veriyor. if [[ $x =~ foo ]]Ancak, harika çalışıyor. Teşekkürler!
DevSolar

1
Bütün bunlar bashislerdir, bash gerektirirler. Ayrıca =~bash> = 3 iirc gerektirir.
inkaphink

1
Iirc ayrıca, foo bu örneklerde (PCRE'de olduğu gibi) normal bir ifade değildir, ancak joker karakterler kullanır. Bash manpage, "Parameter Expansion" bölümünde bu bash iyiliği daha var. Özellikle ${a##foo}ve gibi şeyleri takdir ediyorum ${a%%bar}.
inkaphink

3
Eşleşme operatörü =~düzenli ifadeler kullanır. Bu doğrudur, örneğin: [[ "abcdddde" =~ ^a.*d+.g* ]]( örneğin, g-joker karakteri yerine sıfır veya daha fazla g'dir).
sonraki duyuruya kadar duraklatıldı.

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.