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, pokudbarse 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. -
foohledá 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.