як виконувати операцію grep для всіх файлів у каталозі


219

Працюючи з xenserver, і я хочу виконати команду над кожним файлом, який знаходиться в каталозі, зібравши деякі речі з виводу команди і додавши її у файл.

Я зрозумів команду, яку я хочу використовувати, і як потрібно викреслити рядки (и) за потреби.

Але мені не зрозуміло, як я змушую її виконувати цю команду на кожному файлі, переходячи до наступного, поки не знайдуться більше файлів.

Відповіді:


228

grep $PATTERN *було б достатньо За замовчуванням grep пропустить усі підкаталоги. Однак, якщо ви хочете переглядати їх, grep -r $PATTERN *це справа.


37
"grep -r $ PATTERN." є достатнім. Для рекурсивного grep не потрібно вказувати всі файли
Cougar

1
Як включити кілька розширень? Напр. "* .cpp", "* .h"?
Томаш Зато - Відновити Моніку

1
@ Томаш Zato, просто поставити всі ваші шаблони файлів замість *: grep $PATTERN *.cpp *.h. Якщо вам потрібні більш конкретні правила щодо того, які файли повинні бути вилучені, скористайтеся findкомандою (перевірте відповідь Роба).
umi

@umi Якщо я запускаю grep -r x .результати, надходять з усіх файлів усіх розширень. Якщо я біжу, grep -r x *.scssне отримаю результатів.
Кріс

1
@Chris можливо, у вас немає *.scssфайлів у поточному каталозі, але десь глибше в підкаталогах, так що grep виглядає не у всіх потрібних файлах. Вам слід скористатися --includeопцією, щоб сказати grep, щоб рекурсивно шукати файли, що відповідають певним шаблонам: grep -r x --include '*.scss' . (зверніть увагу на лапки, вони запобігають розширенню шаблону оболонкою). Або просто скористайтеся find(див. Відповідь Роба).
umi

169

У Linux я зазвичай використовую цю команду, щоб рекурсивно переглядати певний текст у межах dir

grep -rni "string" *

де,

r = рекурсивний, тобто пошук підкаталогів у поточному каталозі
n = для друку номерів рядків до stdout
i = нечутливий пошук у регістрі


32

Скористайтеся знахідкою. Якщо серйозно, це найкращий спосіб, тому що тоді ви дійсно можете побачити, на яких файлах він працює:

find . -name "*.sql" -exec grep -H "slow" {} \;

Зауважте, -H є мак-специфічним, він показує ім'я файлу в результатах.


7
Якщо ви вирішили скористатися функцією find, передача результатів, xargsа не використання -execцього буде набагато швидше, оскільки -execпороджує новий процес для кожного грепу, а накладні витрати набувають значного значення з великою кількістю файлів. До них застосовуються стандартні попередження про пробіли у назвах файлів xargs.
Barton Chittenden

2
Як би це виглядало саме? Я завжди забуваю xargsсинтаксис.
Брайан Петерсон

3
@BrianPeterson це було б щось подібне:find . -iname "*.sql" -print0 | xargs -0 grep "slow"
MediaVince

4

Для пошуку у всіх підкаталогах, але лише у певних типах файлів , використовуйте grep with --include.

Наприклад, пошук рекурсивно в поточному каталозі, для тексту в * .yml та * .yaml:

grep "text to search" -r . --include=*.{yml,yaml}

1

Якщо ви хочете зробити кілька команд, ви можете використовувати:

for I in `ls *.sql`
do
    grep "foo" $I >> foo.log
    grep "bar" $I >> bar.log
done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.