Почему этот grep для строки во всех подкаталогах не работает?

Почему этот grep для строки во всех подкаталогах не работает?

Это команда, которую я пытаюсь выполнить.

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.

Связанный контент