Komu a výrazy s grep potřebujete dvě vyvolání:
grep -Ei "search term" | grep -Eiv "exclude term"
Pokud výrazy, které hledáte, nejsou regulární výrazy, použijte shodu s pevným řetězcem (-F
), který je rychlejší:
grep -F "search term" | grep -Fv "exclude term"
Kromě toho, že grep vyvolám dvakrát, existuje pouze jeden způsob, jak toho dosáhnout. Zahrnuje to Perl Compatible Regular Expressions (PCRE) a některá poněkud otřepaná tvrzení.
Chcete-li vyhledat foo s výjimkou shod, které obsahují bar , můžete použít:
grep -P '(?=^((?!bar).)*$)foo'
Funguje to takto:
-
(?!bar)
odpovídá všemu, co není bar bez spotřebovávání znaků z řetězce. Poté.
spotřebuje jeden znak. -
^((?!bar).)*
opakuje výše uvedené od začátku řetězce (^
) až na jeho konec ($
). Selže, pokudbar
se vyskytuje v kterémkoli daném bodě, od(?!bar)
nebude odpovídat. -
(?=^((?!bar).)*$)
zajišťuje, že řetězec odpovídá předchozímu vzoru, aniž by spotřebovával znaky z řetězce. -
foo
hledá foo jako obvykle.
Našel jsem tento hack v regulárním výrazu, který odpovídá řetězci, který neobsahuje slovo?. V odpovědi Barta Kierse můžete najít mnohem podrobnější vysvětlení toho, jak negativní výhled funguje.
Pokud to chcete udělat v jednom průchodu, můžete místo grep použít awk.
Formát:
echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'
Příklady:
echo "hello there" | awk '/hello/ && !/there/'
Nevrací nic.
echo "hello thre" | awk '/hello/ && !/there/'
Návraty:ahoj tři
echo "hllo there" | awk '/hello/ && !/there/'
Nevrací nic.
V případě více vzorů je můžete seskupit pomocí závorek.
Příklady:
echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'
Návraty:ahoj tři
echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'
Návraty:ahoj tři
echo "hello there" | awk '(/hello/ || /hi/) && !/there/'
Nevrací nic.
echo "hi there" | awk '(/hello/ || /hi/) && !/there/'
Nevrací nic.