Bir dosyada bunun veya bunun için (2 şey) nasıl grep yapabilirim?


37

Ben "sonra" ve "orada" olan bir dosyam var.

yapabilirim

$ grep "then " x.x
x and then some
x and then some
x and then some
x and then some

ben de yapabilirim

$ grep "there " x.x
If there is no blob none some will be created

Tek bir işlemde ikisini de nasıl arayabilirim? denedim

$ grep (then|there) x.x

-bash: beklenmedik belirteci `('yakınındaki sözdizimi hatası

ve

grep "(then|there)" x.x
durrantm.../code
# (Nothing)

Yanıtlar:


53

İfadeyi tırnak içine almanız gerekir. Aldığınız hata, bash'ın (özel bir karakter olarak yorumlanmasının sonucudur .

Ayrıca, genişletilmiş düzenli ifadeleri kullanmak için grep'e bildirmeniz gerekir.

$ grep -E '(then|there)' x.x

Genişletilmiş düzenli ifadeler olmadan, kaçmak zorunda |, (ve ). Burada tek tırnak işareti kullandığımızı unutmayın. Bash, özel olarak çift tırnak içinde ters eğik çizgi davranır.

$ grep '\(then\|there\)' x.x

Bu durumda gruplama gerekli değildir.

$ grep 'then\|there' x.x

Böyle bir şey için gerekli olacaktır:

$ grep 'the\(n\|re\)' x.x

3
Ayrıca bakınız grep $'then\nthere've grep -e then -e there. Not \|Bres standart değildir. Dinlenme. Özel olarak çift tırnak içine Bash davranır tersbölüler önce sadece ", $, \ , `ve yeni satır.
Stéphane Chazelas,

1
Amacı nedir x.x?
alex

7

Sadece hızlı bir zeyilname, çoğu tatların sadece -E ile grep egrep adında bir komutu vardır. Şahsen yazmayı daha çok seviyorum.

egrep "i(Pod|Pad|Phone)" access.log

Grep kullanmak-e


2

(Veya en azından benim) man sayfasındaki REGULAR EXPRESSIONS altında belgelenen şeyler aslında genişletilmiş regexps içindir;

grep, normal ifade sözdiziminin üç farklı versiyonunu anlar: “basic,” “genişletilmiş” ve “perl.” GNU grep'te, temel ve genişletilmiş sözdizimleri arasında kullanılabilir işlevsellik açısından bir fark yoktur. Diğer uygulamalarda, temel düzenli ifadeler daha az güçlüdür. Aşağıdaki açıklama genişletilmiş düzenli ifadeler için geçerlidir; Temel düzenli ifadelerin farklılıkları daha sonra özetlenir.

Ama grep bunları varsayılan olarak kullanmaz - İhtiyacınız -Eanahtarı:

grep "(then|there)" x.x

Çünkü (yine man sayfasından):

Temel ve Genişletilmiş Düzenli İfadeler

Temel düzenli ifadelerde meta-karakterler?, +, {, |, (, Ve) özel anlamlarını kaybeder; bunun yerine backslashed sürümlerini \ ?, +, {, \ |, (, ve) kullanın.

Yani kullanabilirsiniz:

grep "then\|there" x.x

Parantez bu durumda gereksiz olduğundan.


0

Bash'in zarif sadeliği, büyük adam sayfasında kayboluyor gibi görünüyor.

Yukarıdaki mükemmel çözümlere ek olarak, bash'ın ifadeleri nasıl ayrıştırıp yorumladığı konusunda size bir hile sayfası vermeye çalışacağımı düşündüm . Sonra bu yol haritasını kullanarak, neden amaçlanan şekilde çalışmadıklarını daha iyi anlamanıza yardımcı olmak için sorgulayıcı tarafından sunulan örnekleri inceleyeceğim.


Not: Kabuk betiği satırları doğrudan kullanılır. Yazılan giriş satırları ilk önce genişletilir.

Her bash çizgisi ilk önce tokenize edilir veya bir başka deyişle belirteçler olarak adlandırılan şeye doğrar . (Tokozlama, parantez, tilde, parametre, komut, aritmetik, işlem, sözcük bölme ve dosya adı genişletme dahil olmak üzere, diğer tüm genişlemeden önce gerçekleşir.)

Burada bir belirteç, giriş satırının bu özel meta karakterlerden biriyle ayrılmış (ayrılmış) bir kısmı anlamına gelir:

space,  - White space...
tab, 
newline,

‘<’,    - Redirection & piping...
‘|’, 
‘>’
‘&’,    - And/Both < | > | >>  .or.  &<file descriptor>

‘;’,    - Command termination

‘(’,    - Subshell, closed by -     ‘)’

Bash başka birçok özel karakter kullanıyor, ancak yalnızca bu 10' ilk belirteçleri üretiyor.

Ancak bu meta karakterlerin bazen bir belirteç içinde kullanılması gerektiğinden, özel anlamlarını almanın bir yolu olması gerekir. Buna kaçan denir. (Yani bir veya daha fazla bir dizi karakter alıntı yaparak ya yapılır Kaçan 'xx..', "xx..") veya bir arka eğik çizgi (yani tek bir karakteri adýnýnönüne \x). (Bundan biraz daha karmaşık çünkü alıntıların da alıntılanması gerekiyor ve çift tırnakların her şeyi alıntılamadığı için, ancak bu sadeleştirme şimdilik yapacak.)

Bash alıntılarını, diğer dillerde olduğu gibi bir metin dizisinden alıntı yapma fikri ile karıştırmayın. Bash içindeki alıntılar arasındakiler karakter dizileri değil, giriş satırının meta karakterlerinden kaçan bölümleridir, böylece belirteçleri sınırlandırmazlar.

Dikkat, 've arasında önemli bir fark var ", ancak bu başka bir gün için.

Kalan çıkmamış meta karakterler daha sonra belirteç ayırıcılar haline gelir.

Örneğin,

$ echo "x"'y'\g
xyg

$ echo "<"'|'\>
<|>

$ echo x\; echo y
x; echo y

İlk örnekte, bir alan sınırlayıcı tarafından üretilen iki simge vardır: echove xyz.

Aynı şekilde 2. örnekte.

Noktalı kaçan üçüncü örnekte, bu nedenle bir boşluk ayırıcı tarafından üretilen 4 belirteçleri vardır echo, x;, echove y. İlk belirteç daha sonra komut olarak çalıştırılır ve sonraki üç belirteçleri girdi olarak alır. 2. echoçalıştırılmadığına dikkat edin.


Hatırlanması gereken önemli şey kaçan karakterler için bu bash ilk görünüyor olduğunu ( ', "ve \) ve sonra bu sırayla, kaçış meta karakter sınırlayıcı arar.

Kaçmazsa, bu 10 özel karakter tokensınırlayıcı olarak işlev görür . Bazılarının ek anlamı da var, ama her şeyden önce belirteç sınırlayıcıları.


Grep ne bekler

Grep'in Yukarıdaki örnek bu belirteçleri ihtiyaç olarak, grep, string, filename.

Sorunun ilk denemesi şuydu:

$ grep (sonra | orada) xx

Bu durumda (, )ve |çıkış kullanılmayan meta karakterler ve böylece bu jeton içine girdi bölmek hizmet: grep, (, then, |, there, ), ve x.x. grep görmek istiyor grep, then|thereve x.x.

Sorunun ikinci denemesi şuydu:

grep "(sonra | orada)" xx

Bu içine sıfırlar grep, (then|there), x.x. Eğer yankı için grep çıkarırsanız bunu görebilirsiniz:

echo "(sonra | orada)" xx
(sonra | orada) xx

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.