Я пытаюсь построить поиск grep, который ищет термин, но исключает строки, имеющие второй термин. Я хотел использовать несколько -e "pattern"
вариантов, но это не сработало.
Вот пример команды, которую я пробовал, и сгенерированного сообщения об ошибке.
grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory
Мне кажется, что это -v
относится ко всем условиям поиска / шаблонам. Как это работает, но затем не включает search term
в результаты.
grep -i -E "search term" -ve "exclude term"
Ответы:
Чтобы и выражения с grep вам нужно два вызова:
Если искомые термины не являются регулярными выражениями, используйте фиксированное сопоставление строк (
-F
), которое быстрее:источник
Если не вызывать grep дважды, я могу придумать только один способ сделать это. Он включает в себя Perl-совместимые регулярные выражения (PCRE) и некоторые довольно хакерские утверждения .
Для поиска foo, исключая совпадения, содержащие строку , вы можете использовать:
Вот как это работает:
(?!bar)
соответствует чему-либо, что не является баром, не потребляя символы из строки. Затем.
потребляет один символ.^((?!bar).)*
повторяет вышеизложенное от начала строки (^
) до ее конца ($
). Он потерпит неудачу, еслиbar
встретится в любой данный момент, так(?!bar)
как не будет совпадать.(?=^((?!bar).)*$)
удостоверяется, что строка соответствует предыдущему шаблону, не потребляя символы из строки.foo
ищет foo как обычно.Я нашел этот хак в регулярном выражении, чтобы соответствовать строке, не содержащей слова? , В ответе Барта Киерса вы можете найти гораздо более подробное объяснение того, как работает негативное прогнозирование.
источник
Если вы хотите сделать это за один проход, вы можете использовать awk вместо grep.
Формат:
echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'
Примеры:
echo "hello there" | awk '/hello/ && !/there/'
Ничего не возвращает
echo "hello thre" | awk '/hello/ && !/there/'
Возвращает: привет три
echo "hllo there" | awk '/hello/ && !/there/'
Ничего не возвращает
Для нескольких шаблонов вы можете использовать круглые скобки для их группировки.
Примеры:
echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'
Возвращает: привет три
echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'
Возвращает: привет три
echo "hello there" | awk '(/hello/ || /hi/) && !/there/'
Ничего не возвращает
echo "hi there" | awk '(/hello/ || /hi/) && !/there/'
Ничего не возвращает
источник
ls --color=always | awk '/hello/ && !/goodbye/'
grep -R
в нескольких файлах кода с помощью командной строки Ubuntu.Из моих экспериментов не имеет особого значения, если вы передадите свои исключающие термины через
grep
илиsed
. Sed имеет некоторые другие полезные функции замены текста, которые я часто использую, чтобы лучше фильтровать выход файлов журнала. Поэтому я собираюсь использовать sed, так как объединяю довольно много фильтров в sed.источник
grep -F
вместоgrep -E
и не используйте,-i
если вам это не нужно.sed
;)