что такое "Linux"??
В моей Ubuntu 12.04 Вам только нужно:
Затем значок CD появляется на сетевой группе файлового браузера.Это все!
С pcregrep
:
pcregrep --include='\.cpp$' -rnM 'Foo(?!(?:.*\n){0,2}.*Bar)' .
Ключ находится в -M
опция, которая уникальна для pcregrep
и используется для соответствия нескольким строкам (pcregrep
получения по запросу больше данных из входного файла по мере необходимости при обходе РЕ требуют это).
(?!...)
perl/PCRE отрицательный предварительный оператор RE. Foo(?!...)
соответствия Foo
пока ...
не соответствует тому, что следует.
...
быть (?:.*\n){0,2}.*Bar
(.
не соответствуя символу новой строки), который является от 0 до 2 строк, сопровождаемых строкой, содержащей Bar
.
Непротестированный, я говорю по телефону:
find . -name "*.cpp" | xargs awk '/foo/{t=$0;c=10}/bar/{c=0;t=""}c{c--}t&&!c{print t;t=""}END&&t{print t}'
что-то как этот.
Неважно просто используйте pcregrep
как предложено @StephaneChazelas.
Это должно работать:
$ find . -name "*.cpp" |
while IFS= read -r file; do
grep -A 3 Foo "$file" | grep -q Bar || echo "$file";
done
Идея состоит в том, чтобы использовать grep's -A
переключитесь для вывода подобранных строк и N после строк. Вы затем передаете результат через a grep Bar
и если это не соответствует (выход> 0), то Вы повторяете название файла.
Если Вы знаете, что у Вас есть нормальные имена файлов (никакие пробелы, новые строки или другие странные символы), можно упростить до:
$ for file in $(find . -name "*.cpp"); do
grep -A 3 Foo "$file" | grep -q Bar || echo "$file";
done
Например:
terdon@oregano foo $ cat a.cpp
1 Foo
2 qwerty
3 qwerty
terdon@oregano foo $ cat b.cpp
1 Foo
2 Bar
3 qwerty
terdon@oregano foo $ cat c.cpp
1 Foo
2 qwerty
3 qwerty
4 qwerty
5. Bar
terdon@oregano foo $ for file in $(find . -name "*.cpp"); do grep -A 3 Foo "$file" | grep -q Bar || echo "$file"; done
./c.cpp
./a.cpp
Отметьте это c.cpp
возвращается несмотря на содержание Bar
потому что строка с Bar
больше чем 3 строки после Foo
. Вы cna управляют количеством строк, которые Вы хотите искать путем изменения значения, передали -A
:
$ for file in $(find . -name "*.cpp"); do
grep -A 10 Foo "$file" | grep -q Bar || echo "$file";
done
./a.cpp
Вот более короткий (предполагающий, что Вы используете bash
):
$ shopt -s globstar
$ for file in **/*cpp; do
grep -A 10 Foo "$file" | grep -q Bar || echo "$file";
done
Как Stephane Chazelas указал в комментариях, вышеупомянутые решения также распечатают файлы, которые не содержат Foo
вообще. Этот избегает что:
for file in **/*cpp; do
grep -qm 1 Foo "$file" &&
(grep -A 3 Foo "$file" | grep -q Bar || echo "$file");
done
Foo
. У Вас есть недостающие кавычки.
– Stéphane Chazelas
14.01.2014, 19:13
Foo
и я зафиксировал это, но я не вижу Вашу точку о нескольких экземплярах Foo
. Это должно иметь дело с ними правильно.
– terdon♦
14.01.2014, 19:30
pcregrep
? Я никогда не слышал о нем прежде. – John Dibling 14.01.2014, 19:57(?!...)
отрицательное предвидениеperl
Оператор RE. – Stéphane Chazelas 14.01.2014, 22:21