agrep
может сделать это с этим синтаксисом:
agrep 'pattern1;pattern2'
С GNU grep
, при создании с поддержкой PCRE можно сделать:
grep -P '^(?=.*pattern1)(?=.*pattern2)'
С ast grep
:
grep -X '.*pattern1.*&.*pattern2.*'
(добавление .*
s как
строки соответствий то соответствие оба
и
точно, a&b
никогда не соответствовал бы, поскольку нет такой строки, которая может быть обоими a
и b
одновременно).
Если шаблоны не накладываются, можно также смочь сделать:
grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'
Лучший портативный путь, вероятно, с awk
как уже упомянуто:
awk '/pattern1/ && /pattern2/'
С sed
:
sed -e '/pattern1/!d' -e '/pattern2/!d'
Остерегайтесь этого всего, у этого будет другой синтаксис регулярного выражения.
Если у Вас есть GNU grep, можно использовать регулярные выражения Perl, которые имеют конструкцию отрицания.
grep -A1 -P '^(?!.*ignore me).*needle'
Если у Вас нет GNU grep, можно эмулировать перед/после того, как опциями контекста в awk.
awk -v after=3 -v before=2 '
/needle/ && !/ignore me/ {
for (i in h) {
print h[i];
delete h[i];
}
until = NR + after;
}
{
if (NR <= until) print $0; else h[NR] = $0;
delete h[NR-before];
}
END {exit !until}
'
Вы, кажется, используете GNU grep. С GNU grep, Вы могли передать в --perl-regex
флаг, чтобы активировать PCRE и затем предоставить отрицательное предварительное утверждение, пример ниже
grep --after-context=1 \
--perl-regex '^(?:(?!ignore me).)*needle(?:(?!ignore me).)*$' file.txt
four needle
five
Знаменитое главное здесь - это (?:(?!STRING).)*
к STRING
как [^CHAR]*
к CHAR
Я предложил бы использовать awk вместо этого, поскольку он обрабатывает многострочный IO лучше. Любой 1) Канал результаты к GNU awk с --\n
как разделитель записей, или 2) Делают все соответствие в awk.
Опция 1
<file grep -A1 needle | awk '!/ignore me/' RS='--\n' ORS='--\n'
Вывод:
four needle
five
--
Отметьте, эта опция ищет целую запись ignore me
, набор FS=1
и соответствие против $1
только выдерживать сравнение с первой строкой.
Опция 2
<file awk 'a-- > 0; $0 ~ re1 && $0 !~ re2 { print $0; a=after }' re1=needle re2='ignore me' after=1
--\n
разделитель между каждой подобранной группой, которая не является там, если группы смежны друг с другом. То, как смежные группы должны быть обработаны, является определенным для задачи, таким образом, это не обязательно неправильно. Опция 2 не зависит от разделителя и не затронута.
– Thor
17.10.2013, 23:59