Bir satırda iki kelime ararken Grep


45

İçinde "limon" ve "pirinç" yazan bir çizgiyi filtrelemenin bir yolunu bulmaya çalışıyorum. "Limon" veya "pilav" nasıl bulacağımı biliyorum ama ikisini değil. Diğerlerinin yanında olmaları gerekmez, sadece aynı metin satırı.


1
Bir dosya içindeki dizeleri tüm bulmak için, döngü İÇİN grep çalıştırabilirsiniz: unix.stackexchange.com/a/462445/43233
Noam Manos

Yanıtlar:


61

"Her ikisi de aynı satırda", "pirinci", ardından rasgele karakterlerin ardından "limon" veya diğer şekilde "anlamına gelir" anlamına gelir.

Regex içinde rice.*lemonya da lemon.*rice. Bunu kullanarak birleştirebilirsiniz |:

grep -E 'rice.*lemon|lemon.*rice' some_file

Genişletilmiş olanlar yerine normal regex kullanmak istiyorsanız ( -E) aşağıdakilerden önce ters eğik çizgi gerekir |:

grep 'rice.*lemon\|lemon.*rice' some_file

Hızlı bir şekilde biraz uzayan daha fazla kelime grepiçin ve örneğin birden fazla çağrı kullanmak genellikle daha kolaydır :

grep rice some_file | grep lemon | grep chicken

Sizin son satırı bir olduğunu birlikte değil parçalanma yok? Zekâ: grep riceiçeren satırları bulur rice. İçine grep lemonyalnızca limon içeren çizgiler bulacağı .. ve benzerleri uygulanır. Oysaki OP - önceki cevaplarınız gibi - [pirinç | limon | tavuk] herhangi birine izin veriyor
javadba

Komut dosyası sürümü: askubuntu.com/a/879253/5696
Jeff

@Florian Diesch - neden Zihin açıklayan |ihtiyaçları kaçan edilecek grep? Teşekkürler!
kaçak

1
@fugitive egrep, |OR mantığı olarak anlaşılan genişletilmiş regex kullanır . greptemel regex varsayılanları \|, OR nerede
Sergiy Kolodyazhnyy

grep'İn sayfasında belirtildiği gibi egrep, kullanımdan kaldırılmıştır ve değiştirilmesi gerekir grep -E. Buna göre cevabı düzenleme özgürlüğünü kullandım.
tatlılar

26

İlk grep komutunun çıktısını başka bir grep komutuna yönlendirebilirsiniz ve bu her iki kalıbla eşleşir. Yani, şöyle bir şey yapabilirsiniz:

grep <first_pattern> <file_name> | grep <second_pattern>

veya,

cat <file_name> | grep <first_pattern> | grep <second_pattern>

Örnek:

Hadi dosyamıza bazı içerikler ekleyelim:

$ echo "This line contains lemon." > test_grep.txt
$ echo "This line contains rice." >> test_grep.txt
$ echo "This line contains both lemon and rice." >> test_grep.txt
$ echo "This line doesn't contain any of them." >> test_grep.txt
$ echo "This line also contains both rice and lemon." >> test_grep.txt

Dosya ne içeriyor:

$ cat test_grep.txt 
This line contains lemon.
This line contains rice.
This line contains both lemon and rice.
This line doesn't contain any of them.
This line also contains both rice and lemon.

Şimdi, ne istediğimizi öğrenelim:

$ grep rice test_grep.txt | grep lemon
This line contains both lemon and rice.
This line also contains both rice and lemon.

Yalnızca her iki kalıbın eşleştiği çizgileri alırız. Bunu uzatabilir ve daha fazla "VE" eşleşmesi için çıktıyı başka bir grep komutuna yönlendirebilirsiniz.


21

Her ne kadar soru 'grep' sorsa da, basit bir 'awk' çözümü göndermenin faydalı olabileceğini düşündüm:

awk '/lemon/ && /rice/'

Bu, daha fazla sözcükle veya 've' dışında başka boolean ifadelerle kolayca genişletilebilir.


11

Herhangi bir sırada eşleşmeleri bulmak için başka bir fikir kullanıyor:

grep -P (Perl-Compatibility) seçeneği ve pozitif görünümlü regex ile(?=(regex)) :

grep -P '(?=.*?lemon)(?=.*?rice)' infile

veya bunun yerine aşağıdan kullanabilirsiniz:

grep -P '(?=.*?rice)(?=.*?lemon)' infile
  • .*?Herhangi bir karakter eşleşen araçları .oluşumları kez sıfır ya da daha fazla olduğu *bir model (ardından isteğe bağlı iken riceya da lemon). ?O (vasıta sıfır veya her şeyin bir zamanı eşleşti önce her şeyin isteğe bağlı hale .*)

(?=pattern): Pozitif Bakış Açısı: Pozitif bakış açısı yapısı, parantez içinde açılan ve parantez içinde bir soru işareti ve eşittir işareti olan bir çift parantezdir.

Böylece bu, tüm satırları içeren lemonve ricerastgele sırada olan tüm satırları döndürür . Ayrıca bu |s'yi kullanmaktan kaçınır ve s'yi iki katına grepçıkarır.


Dış bağlantılar: Gelişmiş Grep Konuları Olumlu Bakış - Tasarımcılar için GREP


5
grep -e foo -e goo

Foo veya goo için eşleşmeleri döndürür


1

grepTemelli olmayan bir cevap vermenin kabul edilebilir olduğunu kabul edersek , yukarıdaki cevaba dayanarak, aşağıdaki gibi awkbasit bir perlsatır öneririm:

$ perl -ne 'print if /lemon/ and /rice/' my_text_file

Arama, kelimelerin bazıları / tümü ile durumu görmezden gelebilir /lemon/i and /rice/i. Çoğu Unix / Linux makinede perl zaten awk olarak kurulur.


Reddedildi !!! ;) Çünkü hiçbir anlam ifade etmiyor .. :)
An0n

0

Grep borulama çözümünü otomatikleştirmek için bir komut dosyası:

#!/bin/bash

# Use filename if provided as environment variable, or "foo" as default
filename=${filename-foo}

grepand () {
# disable word splitting and globbing
IFS=
set -f
if [[ -n $1 ]]
then
grep -i "$1" ${filename} | filename="" grepand "${@:2}"
else
# If there are no arguments, assume last command in pipe and print everything
cat
fi
}

grepand "$@"

1
Bu muhtemelen bir komut dizesi oluşturmak ve evalonu kolayca
çözmek

@muru Bir düzenleme önermek için çekinmeyin. Yorumunuz için teşekkür ederim.
Jeff,

1
Bunu düzenlemek çok yeniden yazılacak, bu yüzden bunu yapmayacağım. Eklemek istiyorsanız, işte nasıl görünmesi gerektiğini hayal ediyorum: paste.ubuntu.com/23915379
muru
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.