Предположим, я хочу найти во всем дереве все файлы CPP, где встречается «Foo». Я мог бы сделать:
find . -name "*.cpp" | xargs grep "Foo"
Теперь предположим, что я хочу перечислить только те случаи, когда какая-то другая строка, скажем, «Бар», не встречается в пределах 3 строк предыдущего результата.
Итак, дано два файла:
a.cpp
1 Foo
2 qwerty
3 qwerty
b.cpp
1 Foo
2 Bar
3 qwerty
Я хотел бы построить простой поиск, где «Foo» из a.cpp находится, но «Foo» из b.cpp нет.
Есть ли способ сделать это довольно простым способом?
Ответы:
С
pcregrep
:Ключ находится в
-M
опции, которая уникальнаpcregrep
и используется для сопоставления нескольких строк (по мере необходимостиpcregrep
извлекает больше данных из входного файла, когда RE требует этого).(?!...)
является оператором RE отрицательного прогнозирования perl / PCRE.Foo(?!...)
соответствуетFoo
до тех пор, пока...
не совпадает с тем, что следует....
будучи(?:.*\n){0,2}.*Bar
(.
не соответствует символу новой строки), то есть от 0 до 2 строк, за которыми следует строка, содержащаяBar
.источник
pcregrep
? Я никогда не слышал об этом раньше.(?!...)
отрицательнымperl
прогнозом.Не берите в голову, просто используйте
pcregrep
как предложено @StephaneChazelas.Это должно работать:
Идея состоит в том, чтобы использовать
-A
переключатель grep для вывода совпавших строк и N следующих строк. Затем вы передаете результат через a,grep Bar
и если он не совпадает (выход> 0), вы выводите имя файла.Если вы знаете, что у вас есть правильные имена файлов (без пробелов, новых строк или других странных символов), вы можете упростить:
Например:
Обратите внимание, что
c.cpp
возвращается несмотря на содержание,Bar
потому что строка сBar
более чем 3 строки послеFoo
. Вы можете контролировать количество строк, которые вы хотите найти, изменив значение, переданное-A
:Вот более короткий (если вы используете
bash
):ВАЖНЫЙ
Как отметил Стефан Чазелас в комментариях, вышеупомянутые решения также будут печатать файлы, которые вообще не содержат
Foo
. Этот избегает того, что:источник
Foo
. Вы пропустили цитаты.Foo
и я исправил это, но я не вижу вашей точки зрения о нескольких случаяхFoo
. Надо правильно с ними справляться.Не проверено, я на моем телефоне:
что-то подобное.
источник