İç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ı.
İç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ı.
Yanıtlar:
"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.*lemon
ya 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 grep
için ve örneğin birden fazla çağrı kullanmak genellikle daha kolaydır :
grep rice some_file | grep lemon | grep chicken
grep rice
içeren satırları bulur rice
. İçine grep lemon
yalnızca limon içeren çizgiler bulacağı .. ve benzerleri uygulanır. Oysaki OP - önceki cevaplarınız gibi - [pirinç | limon | tavuk] herhangi birine izin veriyor
|
ihtiyaçları kaçan edilecek grep
? Teşekkürler!
egrep
, |
OR mantığı olarak anlaşılan genişletilmiş regex kullanır . grep
temel regex varsayılanları \|
, OR nerede
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.
İ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>
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.
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 rice
ya 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 lemon
ve rice
rastgele 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
grep
Temelli olmayan bir cevap vermenin kabul edilebilir olduğunu kabul edersek , yukarıdaki cevaba dayanarak, aşağıdaki gibi awk
basit bir perl
satı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.
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 "$@"
eval
onu kolayca