Yanıtlar:
Açgözlü olmayan (veya tembel) bir eşleşme arıyorsunuz. Düzenli ifadelerde açgözlü olmayan bir eşleşme elde etmek ?
için niceleyiciden sonra değiştiriciyi kullanmanız gerekir . Örneğin değiştirebilir .*
için .*?
.
Varsayılan olarak grep
, açgözlü olmayan değiştiricileri desteklemez, ancak grep -P
Perl sözdizimini kullanmak için kullanabilirsiniz.
.
yeni satırlarla eşleşmeye izin veren moda DOTALL veya tek satır modu denir ; Ruby ona çok satırlı diyen tek kişidir . Diğer tatlarda, çok hatlı , çapaların ( ^
ve $
) çizgi sınırlarında eşleşmesini sağlayan moddur . Ruby'nin eşdeğer bir modu yoktur, çünkü Ruby'de her zaman bu şekilde çalışırlar.
-P
üzerimde yepyeni bir şeydi, yıllardır mutlu bir şekilde selamlıyorum ve sadece -E
boşa harcanan yıllar ... - Kendine not: Man sayfalarını (daha da fazla!) Normal bir şey olarak tekrar okuyun, asla yeterli anahtar ve seçeneği sindirmezsiniz.
grep
desteklenmez -P
, ancak kullanırsanız aynı sonucu elde etmek için deseni egrep
kullanabilirsiniz .*?
. egrep -o 'start.*?end' text.html
-P
ancak -E
bu egrep
nedenle önerilen .*?
işler gayet iyi çalışır.
Aslında .*?
sadece çalışıyor perl
. Eşdeğer grep genişletilmiş regexp sözdizimi ne olacağını emin değilim. Neyse ki grep ile perl sözdizimini kullanabilirsiniz , grep -P
ancak işe yarayacak grep -E
olanla aynıdır egrep
(açgözlü olurdu).
Ayrıca bkz: http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html
grep -P
GNU grep 2.9'da çalışmıyor - sadece denedi (hata yapmaz, sadece sessizce uygulanmaz ?
. Intertestly de sınıf değil örneğin:env|grep '[^\=]*\='
grep -P
seçenek veya pgrep
komut yok , ama egrep
harika çalışıyor.
pgrep
OS X 10.9 kutumda bir komut var, ancak amacı "süreçleri ada göre bulmak veya işaretlemek" olan tamamen farklı bir program.
Bu konuda şeyler denedikten sonra çalışan benim grep:
echo "hi how are you " | grep -shoP ".*? "
Satırlarınızın her birine bir boşluk eklediğinizden emin olun
(Mine, kelimeleri tükürmek için satır satır arandı)
-shoP
güzel anımsatıcı :)
echo "bbbbb" | grep -shoP 'b.*?b'
biraz öğrenme deneyimidir. Benim için açıkça tembel olarak da işe yarayan tek şey.
grep
Açgözlü olmayan eşleşme grep
için reddedilen bir karakter sınıfı kullanabilirsiniz. Başka bir deyişle, joker karakterlerden kaçınmaya çalışın.
Örneğin, jpeg dosyalarına yapılan tüm bağlantıları sayfa içeriğinden almak için şunu kullanırsınız:
grep -o '"[^" ]\+.jpg"'
Birden fazla hatla başa çıkmak için önce girişi boruya geçirin xargs
. Performans için kullanın ripgrep
.
Kısa cevap bir sonraki normal ifadeyi kullanmaktır:
(?s)<car .*? model=BMW .*?>.*?</car>
(Daha az) daha karmaşık bir cevap:
(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>
Bu, aşağıdaki metinde car1 ve car2 ile eşleşmeyi mümkün kılacaktır
<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
Maalesef 9 yıl geç kaldım, ancak bu 2020'de izleyiciler için işe yarayabilir.
Diyelim ki böyle bir çizginiz var "Hello my name is Jello"
. Şimdi ile başlayan 'H'
ve 'o'
aralarındaki herhangi bir sayıda karakterle biten kelimeleri bulmak istiyorsunuz . Ve çizgiler istemiyoruz, sadece kelimeler istiyoruz. Bunun için şu ifadeyi kullanabiliriz:
grep "H[^ ]*o" file
Bu tüm kelimeleri döndürecektir. Bunun çalışma şekli şudur: Aradaki boşluk karakteri yerine tüm karakterlere izin verir, böylece aynı satırda birden çok kelimeden kaçınabiliriz.
Artık boşluk karakterini istediğiniz herhangi bir karakterle değiştirebilirsiniz. İlk satırın olduğunu varsayalım "Hello-my-name-is-Jello"
, o zaman ifadeyi kullanarak kelimeler alabilirsiniz:
grep "H[^-]*o" file
Biraz ölü bir yazı olduğunu biliyorum ama bunun işe yaradığını fark ettim. Hem temizliği hem de temizlemeyi çıktımdan kaldırdı.
> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20