![Почему этот grep для строки во всех подкаталогах не работает?](https://rvso.com/image/886380/%D0%9F%D0%BE%D1%87%D0%B5%D0%BC%D1%83%20%D1%8D%D1%82%D0%BE%D1%82%20grep%20%D0%B4%D0%BB%D1%8F%20%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8%20%D0%B2%D0%BE%20%D0%B2%D1%81%D0%B5%D1%85%20%D0%BF%D0%BE%D0%B4%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%B0%D1%85%20%D0%BD%D0%B5%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82%3F.png)
Это команда, которую я пытаюсь выполнить.
grep -r "printf" *.c
Я пытаюсь получить все строки printf из всех .c
файлов, присутствующих в моем cwd. На данный момент мой текущий каталог — Desktop, и у меня есть по крайней мере 10-15 .c
файлов в моих подкаталогах в Desktop, но эта команда вообще не показывает никаких совпадений. Так как мне заставить это работать в этом случае?
решение1
Если вы это сделаете:
grep -r "printf" *.c
Оболочка расширит список *.c
на все файлы/каталоги, имена которых заканчиваются .c
на ваш текущий каталог. Если такого файла/каталога не существует, шаблон будет интерпретироваться буквально (вероятно, вы его не установили nullglob
).
Как видите, ваш текущий шаблон никогда не попадает ниже текущего каталога, поскольку в текущем каталоге нет ни одного .c
файла, а если они и есть, то их там нет printf
, что приводит к пустому выводу.
Вам нужно использовать --include
для поиска только в выборочных файлах, а также -r
для рекурсивного обхода:
grep -r --include="*.c" "printf" .
Вышеприведенный код будет искать .c
строку (шаблон) во всех файлах printf
, рекурсивно начиная с текущего каталога.
если вы хотите перейти по всем символическим ссылкам:
grep -R --include="*.c" "printf" .
решение2
Если вы хотите узнать, почему ваша команда не работает, см.другой ответ. Если вы хотите узнать, как это работает, вот еще один подход (скопирован из
Grep в файлах с определенным расширением в каталоге
с косметическими локализациями),
который использует возможности , bash
а не возможности grep
(и поэтому будет работать для любой команды, например wc
, cp
или tar
, а не только grep
):
Сэт (включить)шэллвыбратьион globstar
с командой
shopt -s globstar
Это приведет к **
тому, что компонент имени файла будет означать все, что здесь и ниже. Так что, если вы находитесь в Desktop
, то **
означает все в Desktop
каталоге
и его подкаталоги. Тогда вы можете использовать
grep "printf" **/*.c
для поиска по всем .c
файлам в и под Desktop
. Вам не нужно указывать -r
, потому что оболочка выполняет рекурсию за вас, и вам не нужно указывать --include
, потому что шаблон расширения имени пути (он же glob или wildcard) содержит *.c
.
Ты можешьтыпараметры nset с shopt -u
.