\\ ve using \ kullanarak normal ifade


10

Neden yapar

grep e\\.g\\. <<< "this is an e.g. wow"

ve

grep e\.g\. <<< "this is an e.g. wow"

aynı şeyi yap?

Üçüncü bir eğik çizgi eklersem, aynı sonucu verir. AMA, dördüncü eğik çizgi eklediğimde artık çalışmıyor. Bu, bir sınıf için eski bir sınavdan gelen bir soru ile ilgilidir. İki ters eğik çizgiye sahip bir kişinin "örn." Açıklama nedir?


Ben \\\.bash'ın grep alacağını ve vereceğini düşünmüştüm \.ama öyle değil. iyi soru

Yanıtlar:


9

İlk olarak, tek eğik çizginin çok fazla eşleştiğine dikkat edin:

$ echo $'eegg \n e.g.' | grep e\.g\.
eegg
 e.g.

Bildiğim kadarıyla Bash konusu olduğunda, kaçan bir süre bir süre aynıdır. Bash grep dönemini geçirir . Grep için, bir dönem her şeyle eşleşir.

Şimdi düşünün:

$ echo $'eegg \n e.g.' | grep e\\.g\\.
 e.g.
$ echo $'eegg \n e.g.' | grep e\\\.g\\\.
 e.g.
$ echo $'eegg \n e.g.' | grep e\\\\.g\\\\.
$

Bash bir çift eğik çizgi gördüğünde, bunu tek bir eğik çizgiye indirir ve yukarıdaki üç testin ilkinde, istediğimiz gibi, bir noktadan önce tek bir eğik çizgi gören grep'e geçer. Böylece, bu doğru olanı yapar.

Üçlü eğik çizgi ile Bash, ilk ikisini tek bir eğik çizgiye indirir. Sonra görür \.. Kaçan bir dönemin Bash için özel bir anlamı olmadığından, bu düz bir süreye indirgenir. Sonuç, grep'in istediğimiz gibi, bir dönemden önce bir eğik çizgi görmesidir.

Dört eğik çizgi ile Bash, her çifti tek bir eğik çizgiye indirir. Bash iki eğik çizgi ve bir dönem grep için geçer. grep iki eğik çizgiyi ve bir dönemi görür ve iki eğik çizgiyi tek bir gerçek eğik çizgiye indirir . Girişte herhangi bir karakter ve ardından bir eğik çizgi yoksa, eşleşme yoktur.

Sonuncuyu göstermek için, tek tırnak içinde tüm karakterlerin değişmez olduğunu unutmayın. Bu nedenle, aşağıdaki üç giriş satırı verildiğinde, grep komutu yalnızca girişteki değişmez eğik çizgiyle aynı satırda eşleşir:

$ echo 'eegg
e.g.
e\.g\.' |  grep e\\\\.g\\\\.
e\.g\.

Bash'in davranışının özeti

Bash için kurallar

  • İki eğik çizgi tek bir eğik çizgiye indirgenir.

  • Nokta gibi normal bir karakterin önündeki eğik çizgi, sadece normal karakterdir (nokta).

Böylece:

$ echo \. \\. \\\. \\\\.
. \. \. \\.

Tüm bu karışıklığı önlemenin basit bir yolu vardır: Bash komut satırında düzenli ifadeler tek tırnak içine alınmalıdır. Tek tırnak içinde Bash her şeyi yalnız bırakır.

$ echo '\. \\. \\\. \\\\.'  # Note single-quotes
\. \\. \\\. \\\\.

Soru: Bash'in bunu ters eğik çizgi olarak görmesi iki ters eğik çizgi gerektirir (biri kaçış dizisidir, diğeri değişmez ters eğik çizgi). Peki, 3 olduğunda bash üçüncü kümeye bir kaçış dizisi olarak da davranır mı? Hiçbir şeyden kaçtığı için atılır mı?
Franz Kafka

@DanielAmaya Üçüncüsü, takip eden karakter için bir kaçış olarak değerlendirilir. Bizim durumumuzda, bu karakter dönemdir ve bash için (grep'in aksine) kaçan bir dönem sadece düz bir dönemdir. sonra bash düz dönemi grep'e aktarır.
John1024

@DanielAmaya echoBu durumlarda bash'ın ne yaptığını gösteren bir ifade için güncellenmiş cevaba bakınız .
John1024

2
@DanielAmaya Her iki durumda da bash ilk iki eğik çizgiyi tek bir eğik çizgiye indirger. Geriye kalan \.ya .. Bash için, her ikisi de aynıdır: düz bir döneme eşdeğerdir. Dolayısıyla, toplamda bash'ın grep'e verdiği şey her ikisi için de aynıdır: tek bir eğik çizgi ve bir nokta.
John1024

1
Sadece küçük bir ekleme - kullanma echo, bu programın birçok uygulaması nedeniyle regexp test etmek için çok güvenilir bir yol değildir. Örneğin benim zsh altında (yerleşik yankı) echo \. \\. \\\. \\\\. \\\\\.verir . \. \. \. \., ancak /bin/echo \. \\. \\\. \\\\. \\\\\.geri döner . \. \. \\. \\.. Böyle bir printf "%s" ...şey muhtemelen daha iyi bir yoldur.
jimmij

4

Çıktı sadece dizeniz için aynıdır, ancak genel olarak bu düzenli ifadeler farklı şeyler yapar. İkinci kalıp e,g,(koma ile), üçüncü e\.g\.(nokta), dördüncü e\,g\,(koma) ve -oyalnızca eşleşen parçaları yazdırmak için grep seçeneği ekleyerek örneğinizi biraz değiştirelim .

  • Aşağıdaki durumda .(haber herhangi bir karakter eşleşmesi ''etrafında e.g.bunu daha sonra gelecek)

    $ grep -o 'e.g.' <<< grep -o 'e.g.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,'
    e.g.
    e,g,
  • Sonra .ters eğik çizgi ile kaçıyoruz \, bu yüzden sadece değişmez .eşleşecek:

    $ grep -o 'e\.g\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,'
    e.g.
  • Ama \başka biriyle kaçabiliriz \, böylece değişmez \eşleşme ve ardından .(yani herhangi bir karakter) eşleşir :

    $ grep -o 'e\\.g\\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,'
    e\.g\.
    e\,g\,
  • Ama biz sadece eşleştirmek istiyorsanız, \.değil \,o zaman henüz başka \noktanın özel bir anlamı kaçmak için gereklidir:

    $ grep -o 'e\\\.g\\\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,'
    e\.g\.

Şimdi, ''grep argümanını kullanmadığınız için, kabuk yorumlamasından ters eğik çizgilerden kaçmak için başka bir ters eğik çizgi eklemeniz gerekir, bu yüzden:

grep 'e\.g\.'     => grep e\\.g\\.
grep 'e\\.g\\.'   => grep e\\\\.g\\\\.  (each backslash has to be quoted separately)
grep 'e\\\.g\\\.' => grep e\\\\\\.g\\\\\\. (3 x 2 = 6 backslashes in total)

3

Bir yaptığınızda grep e\.g\., kabuk ters eğik çizgiyi tüketir, böylece grep e.g.eşleşen bir a yaparsınız . Bir yaptığınızda grep e\\.g\\., kabuk yine bir eğik çizgi tüketiyor ve şimdi grep e\.\g.yine eşleşen bir a yapıyorsunuz . Şimdi, kabuğa ters eğik çizgi benziyor \\. Yani, sahip olduğunuzda \\, birincisi bir kaçış dizisidir, ikincisi gerçek bir ters eğik çizgi. Bir yaptığınızda grep e\\\.g\\\., yine de olur grep e\.\g., çünkü \ilk önce \bir değişmez yapmak için bir kaçış dizisi ( ) yoktur \. Unutmayın \ bir ters eğik çizgi olduğundan, net bir şekilde eşleşmeyen grep e\\\\.\\\\gvarlık olur grep e\\.g\\..

Kabuğun ne yaptığınızı nasıl gördüğünü görmek için echo (ör. echo grep e\\.g\\. <<< "this is an e.g. wow"Vs. echo grep e\\\\.g\\\\. <<< "this is an e.g. wow") kullanın


0

İki komut yalnızca sizin girdiniz için aynı çıktıyı üretir, aksi takdirde farklıdır. Neler olup bittiğini anlamak için, parametrenin önce bashve sonra nasıl yorumlandığını bilmeliyiz grep.

Bash'dan kaçmak

\\kendisi de dahil olmak üzere aşağıdaki karakterin özel anlamını iptal eden özel bir karakterdir . Aşağıdaki karakterin özel bir anlamı yoksa, değiştirilmeden geçirilir. Komut ve sonuç içeren örnekler:

  • echo \a: a- kaçan sıradan karakter karakteri verir
  • echo \\: \- kaçan özel karakter karakteri verir
  • echo \\\a: \a- özel, sıradan kombinasyon
  • echo \\\\: \\- özel kombinasyon, özel

echoortaya çıkan dizgiyi bashyorumladıktan sonra yazdırır . Daha fazla bilgi: bash belgeleri , bash hacker wiki , POSIX özellikleri .

.özel bir anlamı yoktur bash. Kabuk için sıradan bir karakter. Aşağıda örneklerinizle ilgili sekanslar verilmiştir:

  • echo .: .
  • echo \.: .
  • echo \\.: \.
  • echo \\\.: \.
  • echo \\\\.: \\.

Bash'daki gerçek dizeler için daha basit çözüm

Parametreleri tam anlamıyla iletmek bashiçin tek tırnak 'işareti kullanabilirsiniz . Tek tırnak işaretleri arasında karakterlerin özel anlamını önemsemeniz gerekmez, çünkü tek tırnak burada özel bir anlamı olan tek karakterdir. Dizenin ilk bölümünü ekledikten sonra tek bir tırnak ekleyebilirsiniz. Örnek
echo 'part1'\''part2': part1'part2

Grep'te normal ifade

\ile benzer anlama sahip bir kaçış karakteri bash. herhangi bir karakterin tek bir oluşumunu temsil. eden özel bir karakterdir . Bakınız: POSIX normal ifadesi , GNU grep normal ifadesi . Normal ifade ifadelerine örnekler:

  • .- aveya gibi herhangi bir karakterle eşleşir.
  • \.- sadece .kelimenin tam anlamıyla eşleşir

Örnekleriniz

Her örnekte ikinci satırda Eğer tek tırnak ile eşdeğer bulacaksınız aşağıda 'değişmez dize geçtiği gösteren bashetmek grep. Sonra grepkaçış gerçekleştirir sonra örneklerde mümkün olan tek özel karakter .herhangi bir karakter eşleşiyor. Üçüncü satırda, ifadenin eşleştiği bir açıklama bulunur.

  • grep e.g. <<< "this is an e.g. wow"
    grep 'e.g.' <<< "this is an e.g. wow"
    eherhangi bir karakter gherhangi bir karakter - maçlar e.g.ve muhtemelen diğer dizeleri gibieagb
  • grep e\.g\. <<< "this is an e.g. wow"
    grep 'e.g.' <<< "this is an e.g. wow"
    eherhangi bir karakter gherhangi bir karakter - maçlar e.g.ve muhtemelen diğer dizeleri gibiexgy
  • grep e\\.g\\. <<< "this is an e.g. wow"
    grep 'e\.g\.' <<< "this is an e.g. wow"
    e.g.tam anlamıyla - yalnızca eşleşmelere.g.
  • grep e\\\.g\\\. <<< "this is an e.g. wow"
    grep 'e\.g\.' <<< "this is an e.g. wow"
    e.g.tam anlamıyla - yalnızca eşleşmelere.g.
  • grep e\\\\.g\\\\. <<< "this is an e.g. wow"
    grep 'e\\.g\\.' <<< "this is an e.g. wow"
    e\herhangi bir karakter g\herhangi bir karakter - eşleşmiyore.g.
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.