Grep ile bir kalıbı nasıl eşleştirebilirim ve başka bir kalıbı nasıl eşleştirebilirim?


11

İle grep, bir kalıpla eşleşen ve başka bir kalıpla eşleşmeyen tüm satırları seçmek istiyorum. Seçeneği (veya , veya ) kullanabilmem için tek bir çağırma grepözelliğini kullanmak istiyorum .--after-context--before-context--context

-vBurada geçerli değil, çünkü seçeneği grepkullanarak geçirdiğim tüm desenleri reddediyor -e.

Misal

Aşağıdaki bağlamda bir satır ile needleeşleşen satırları ignore me, satır eşleşen görmezden bakmak istiyorum .

İşte girdi dosyam:

one needle ignore me
two
three
four needle
five

İstediğim çıktı:

four needle
five

Gördüğünüz gibi, bu naif çözüm işe yaramıyor:

$ cat file | grep --after-context=1 needle | grep -v 'ignore me'
two
---
four needle
five

Yanıtlar:



8

GNU kullanıyor görünüyorsunuz . GNU grep ile, --perl-regexPCRE'yi etkinleştirmek için bayrağa geçebilir ve daha sonra negatif bir ileriye dönük beyanı sağlayabilirsiniz, aşağıdaki örnek

grep --after-context=1 \
--perl-regex '^(?:(?!ignore me).)*needle(?:(?!ignore me).)*$' file.txt
four needle
five

Notun önemli şey burada olmasıdır (?:(?!STRING).)*etmektir STRINGolarak [^CHAR]*etmektirCHAR


@ 1_CR ... Efendim .. harika ..: P bir şey için smilerack
Rahul Patil

@RahulPatil. :-), evet GNU grep bu kadar iyi.
iruvar

İstediğim bu değil. "Beni görmezden gel" i "iğne" den önce mi sonra mı çalışmasını istiyorum.
Flimm

@RululPatil, teşekkürler, en son sürümde
sabitledim

Çok kullanışlı. Özellikle yakın eşleşen çizgileri hariç tutmak istediğiniz, ancak kalıbın belirli bir parçası olmayan bağlamlı grep durumunda. Orijinal soruya yakın ama aynı değil.
gaoithe

2

Bunun yerine çok satırlı IO'yu daha iyi işlediğinden awk kullanmanızı öneririm. Ya 1) Boru ile GNU awk için sonuçlar --\nrekor ayırıcı olarak ya da 2) awk 'de eşleme şeyi yapın.

seçenek 1

<file grep -A1 needle | awk '!/ignore me/' RS='--\n' ORS='--\n'

Çıktı:

four needle                                                                                  
five
--

Bu seçeneğin yalnızca ilk satırı karşılaştırmak için tüm kaydı arar ignore me, ayarlar FS=1ve eşleşir $1.

seçenek 2

<file awk 'a-- > 0; $0 ~ re1 && $0 !~ re2 { print $0; a=after }' re1=needle re2='ignore me' after=1

ignore meDosyada birden fazla var mı , awk çalışmıyor
Rahul Patil

@RahulPatil: Sorunuzu yeniden ifade edebilir veya daha fazla ayrıntı ekleyebilir misiniz? Ne istediğini anlamıyorum.
Thor

@Thos bu giriş dosyası ile örneğinizi test edin paste.ubuntu.com/6252860
Rahul Patil

@RahulPatil: Şimdi ne demek istediğinizi görüyorum, Seçenek 1--\n , eşleşen her grup arasında bir sınırlayıcının olduğunu varsayar; bu gruplar birbirine bitişikse orada değildir. Bitişik grupların nasıl ele alınması gerektiği göreve özgüdür, bu yüzden bu mutlaka yanlış değildir. Seçenek 2 ayırıcıya bağlı değildir ve etkilenmez.
Thor
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.