В Windows, если бы я хотел найти строку во всех файлах во всех подкаталогах, я бы сделал что-то вроде
findstr /C:"the string" /S *.h
Тем не менее, в Linux (скажем, Ubuntu) я не нашел другого пути, кроме какой-либо конвейерной команды, включающей find
, xargs
и grep
(пример на этой странице: Как я могу рекурсивно выполнять поиск в подкаталогах? ). Однако у меня другой вопрос: есть ли какая-то одна встроенная команда, которая работает через это волшебство, без необходимости писать мой сценарий оболочки?
*
на'*'
: «Необходимо использовать последний подстановочный знак во избежание ошибок, когда некоторые имена файлов начинаются с -»-Msomething
или сGREP_OPTIONS
настройкой.grep -r searchpattern /path/to/start/in
Где
/path/to/start/in/
может быть просто ".
" для текущего каталога.источник
Нет,
find -name \*.h -print0 | xargs -0 grep -l 'the regex'
это волшебство, какое только возможно.источник
-r
опцию. Нет необходимости в тяжелой артиллерии.xargs
добавляет только шум. Использованиеfind -name \*.h -execdir grep -l 'the regex {} +
Чтобы быть педантичным, нет, вы не можете предполагать, что такая команда существует .
Существует множество различных реализаций Unix, и у каждой есть свои особенности. POSIX, общий знаменатель (и самый близкий к стандарту в Unices) такой параметр не указывает для
grep
.Как упоминалось в других ответах, реализация GNU
grep
имеет нестандартную опцию, которая делает то, что вы хотите. Хотя эта конкретная реализация может быть распространена в системах Linux, вы не можете предполагать ее доступность в любом Unix, даже в некоторых системах Linux.Наконец, я должен отметить, что философия Unix заключается в том, чтобы отдавать предпочтение комбинации нескольких примитивных программ, а не использованию одного большого монолитного исполняемого файла, пытающегося сделать все сразу.
В вашем случае обход файловой системы и сопоставление регулярного выражения в потоке - это две отдельные задачи. Это нормально, чтобы рассматривать каждого в отдельной программе.
источник
Чтобы найти строку из данного каталога, используйте команду ниже
Например:
источник
grep
может принимать более одного файла в качестве аргументов, поэтому вы должны использовать+
вместо того,\;
чтобы избежать запуска одногоgrep
вызова на файл, что довольно неэффективно.-name '*'
относится только к файлам, чье имя является допустимым текстом в текущей локали (find
по крайней мере, в некоторых реализациях), но другие компоненты каталога могут по-прежнему содержать последовательности байтов, которые не образуют допустимых символов. Если вы намерены-name '*'
сделать так, чтобы вывод был корректным текстом (пропуская файлы с неправильными именами), вы бы предпочли использоватьfind ... ! -name '*' -prune -o -exec grep ... {} +
, что также не позволитfind
спускаться в каталоги с неправильными именами.