Мне нужно запустить grep на моем сервере для поиска файлов, которые расширяют файл CodeIgniter 1, поскольку мы обновляемся до CI2. В одной папке содержится несколько сотен специфичных для сайта папок, таких как:
dev/sitea.com/site/www
dev/siteb.com/site/www
dev/sitec.com/site/www
... and so on
Как я могу найти папки с помощью grep непосредственно под dev содержат файл (или несколько файлов в подпапках переменных), который ссылается на строку «MY_Output» (файл php)
Я знаю о -l
флаг, чтобы перечислить файлы, но я не уверен, как поставить его вместе с другими флагами, чтобы сказать "покажи мне, на каких сайтах есть файлы с этой строкой"
Это возможно? Спасибо!
РЕДАКТИРОВАТЬ: Чтобы уточнить, эти папки уровня сайта будут содержать файлы, которые расширяют MY_Output.php, который является общим общим файлом:
class Whatever extends MY_Output
Это был бы мой подход:
find dev -type f -print0 | \ # find all files
xargs -0 grep 'extends MY_Output' | \ # search for your string
cut -d/ -f2 | \ # extract web folder name
sort | uniq # eliminate duplicates
Обратите внимание на использование print0
параметр для find
и -0
(нулевой) флаг для xargs
, что предотвращает проблемы, если ваши имена файлов содержат пробелы.
Я вижу много ненужной сложности в различных опубликованных решениях. Учтите следующее:
grep -r [regex to find] [path to search] | awk -F: '{print $1}' | uniq
Чтобы узнать, на каких веб-сайтах есть файл с MY_output.php внутри, выполните следующие действия:
Войдите на сервер с помощью PuTTY. Вы должны получить такую командную строку:
username@hostname:~$
Перейдите в свой каталог dev (не уверен, где он находится на вашем сервере, возможно, в / var / www?)
cd /var/www/dev
Убедитесь, что мы находимся в правильном каталоге
ls
И у нас должно получиться что-то вроде этого:
sitea.com
siteb.com
sitec.com
Теперь найдите каждый файл, содержащий MY_output.php, затем сократите список до доменов:
grep -rsl "extends MY_output" * | cut -d/ -f1 | sort | uniq
Grep рекурсивно ищет все соответствующие файлы во всех веб-каталогах. Команда cut разбивает ваши пути и дает только имя первого каталога (sitea.com, siteb.com и т. Д.). Команды sort и uniq просто удаляют повторяющиеся записи, поэтому каждый домен появляется только один раз.
Наслаждайтесь!
использовать find
чтобы вывести список всех файлов, а затем запустить grep для каждого из них:
find dev/ | xargs grep -l MY_Output.php
Заметка: вы должны быть в каталоге, содержащем каталог dev
и если вы получаете ошибки нечитаемых файлов (разрешения и т. д.), вы можете добавить 2>/dev/null
find dev/ | xargs grep -l MY_Output.php 2>/dev/null
Если вы войдете на свой сервер, а затем cd в папку dev, это должно сработать:
egrep -rl 'class \S+ extends MY_Output' * | awk -v FS="/" '{print $2}' | sort | uniq -c
Это подберет ТОЛЬКО сайты, у которых действительно есть классы, расширяющие класс MY_Output, а также даст вам количество файлов на этом сайте, которые вы можете ожидать изменить. Вы также можете использовать утилиту cut вместо awk:
egrep -rl 'class \S+ extends MY_Output' * | cut -d/ -f2 | sort | uniq -c
Насколько я понимаю, в общих чертах вы хотите указать, какие папки содержат обычные файлы, называемые dev / * / * которые сами содержат строку "MY_Output" (чувствительный к регистру).
Точнее, поскольку шаблон «*» не соответствует файлам или каталогам, начинающимся с «.», Вам также следует искать dev / * / *, dev /.??*/*, dev /*/.??* и dev /.??*/.??* . Эта деталь отсутствует в решениях secretmike и Брайана Шоуолтера.
Использование этих четырех шаблонов гарантирует, что вы обработаете все нужные файлы и не получите дополнительных совпадений из других (более глубоких или мелких) файлов. Обычно список подходящих файлов можно составить, просто запустив:
grep -l MY_Output dev/*/* dev/.??*/* dev/*/.??* dev/.??*/.??* 2>/dev/null
В 2> / dev / null часть предназначена для игнорирования ошибок, например, когда вы пытаетесь читать из файлов без разрешений, как вы, кажется, делаете (на основе вашего ответа на ответ Имре Л.). Для достижения наилучших результатов вы можете запустить эту команду от имени пользователя root.
К сожалению, существует ограничение на длину командной строки, и эта команда может не работать, если есть слишком много совпадающих файлов, потому что командная строка будет слишком длинной (после расширения). Поскольку вы говорите, что под разработчик, этот подход неуместен, хотя я считаю, что для полноты его стоит упомянуть здесь.
Чтобы избежать этой проблемы, найти Команда лучше подходит:
find dev -mindepth 2 -maxdepth 2 -type f \
-exec bash -c 'grep -q MY_Output {} && echo {}' \;
Это очень похоже на ответ Имре Л., хотя он прибегает к xargs вместо использования -exec переключатель. Но это дает вам только список совпадающих файлов, а не список папок, которые их содержат.
Чтобы получить то, что вы хотите, нам нужно немного отфильтровать его:
find dev -mindepth 2 -maxdepth 2 -type f \
-exec bash -c 'grep -q MY_Output {} && dirname {}' \; \
| sort \
| uniq
В -mindepth и -Максимальная глубина переключатели гарантируют, что мы не получим совпадений из файлов глубже или мельче в разработчик дерево.
Думаю, я бы сделал что-то вроде этого:
for dir in dev/* ; do
if [ -d "$dir" ] ; then
if [ -n "$( find "$dir" -type f \
-exec grep -q '\<MY_Output\>' {} \; \
-print | head -1 )" ] ; then
echo "$dir"
fi
fi
done
Или, как однострочный:
for dir in dev/* ; do [ -d "$dir" ] && [ -n "$( find "$dir" -type f -exec grep -q '\<MY_Output\>' {} \; -print | head -1 )" ] && echo "$dir" ; done
find (Directory) -iname "(File Pattern>)" -exec zgrep "(String to Find)" {} \;
Например:
find /opt/WebSphere/AppServer/profiles/application/logs/ -iname "SystemOut*" -mtime -7 -exec zgrep "FileNotFoundException" {} \;