İç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.*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
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
|ihtiyaçları kaçan edilecek grep? Teşekkürler!
egrep, |OR mantığı olarak anlaşılan genişletilmiş regex kullanır . greptemel 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 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
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.
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 "$@"
evalonu kolayca