Поиск по каждому файлу в каталоге (и в любых подкаталогах) один за другим - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь перебрать все файлы в каталоге (включая файлы в его подкаталогах) и выполнить некоторые действия, если файл соответствует условию if.

Часть моего кода выглядит следующим образом:

for f in $direc/*
do
        if grep -q 'search_term' $f; then
            #action on this file
        fi
done

Однако, это не работает в случае подкаталогов.Буду очень признателен, если кто-нибудь сможет мне помочь.

Спасибо!

Ответы [ 4 ]

0 голосов
/ 24 января 2019

Если в именах файлов нет новых строк:

find "$direc" -type f -exec grep -q 'search_term' {} \; -print |
while IFS= read -r f; do
    #action on this file
done
0 голосов
/ 23 января 2019

Найти | xargs - это обычный шаблон, который я использую, и он имеет преимущество в том, что не зацикливается на специальных символах в именах файлов (пробелы и т. д.), если вы используете опцию -print0 команды find.

find . -type f -print0 | xargs -0 -I{} sh -c "if grep -q 'search string' '{}'; then cmd-to-run '{}'; fi"
0 голосов
/ 23 января 2019

Да, поскольку с этим синтаксисом grep ожидает обработки файлов, а не каталогов. Минимальное изменение в вашем сценарии - проверить, является ли $f файлом или нет:

...
if [ -f "$f" ] && grep -q 'search_term' $f; then
...

На самом деле вы, возможно, захотите получить список файлов с соответствием паттер и действовать на них:

while read f; do
    : #action on file file $f
done < <(grep -rl 'search_term' $direc/)

Я выбрал получение списка файлов через <(list), потому что передача его в while приведет к запуску внутренней части вашего цикла в другом процессе (что может быть проблемой, в частности, если вы ожидаете какой-либо переменная (изменения) должна быть доступна извне. И в отличие от простой для с `` она не так чувствительна к тому, с какими именами файлов вы сталкиваетесь (а именно, я имею в виду пробелы, это все равно будет путать с новыми строками).

while read -d "" f; do
    : #action on file file $f
done < <(grep -rZl 'search_term' $direc/)

Ничто не должно сбивать с толку это, поскольку записи имеют нулевой символ и не должны появляться в имени файла.

0 голосов
/ 23 января 2019

Опция -R для grep будет читать все файлы в дереве каталогов, включая подкаталоги. В сочетании с параметром -l для печати только совпадающих имен файлов, вы можете использовать его для выполнения действий с каждым соответствующим файлом.

egrep -Rl pattern directory | while read path; do echo $path && mv $path /tmp; done

Например, это напечатало бы имя файла и переместило файл в другой каталог.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...