Як зробити рекурсивно grep
всі каталоги та підкаталоги?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
не працює для мене на Redhat Linux. Я отримую помилку "без збігу"
Як зробити рекурсивно grep
всі каталоги та підкаталоги?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
не працює для мене на Redhat Linux. Я отримую помилку "без збігу"
Відповіді:
grep -r "texthere" .
Перший параметр являє собою регулярний вираз для пошуку, а другий - каталог, який слід шукати. У цьому випадку .
означає поточний каталог.
Примітка. Це працює для GNU grep, і на деяких платформах, таких як Solaris, ви повинні спеціально використовувати GNU grep на відміну від застарілої реалізації. Для Solaris це ggrep
команда.
AIX 5.3
наприклад.
Якщо ви знаєте розширення або шаблон файлу, який ви хочете, іншим методом є використання --include
опції:
grep -r --include "*.txt" texthere .
Ви також можете згадати файли, які потрібно виключити --exclude
.
Якщо ви часто шукаєте код, Ag (The Silver Searcher) - це набагато швидша альтернатива grep, яка налаштована для пошуку коду. Наприклад, він за замовчуванням є рекурсивним і автоматично ігнорує файли та каталоги, перелічені в .gitignore
, тому вам не доведеться продовжувати передавати ті самі громіздкі параметри виключення, щоб отримати копію або знайти.
=
роботи на Ubuntu працює чудово. PS: це повинно бути відтворений простір, але аналізатор розмітки SO не вдався.
grep
, а не за агента , просто так ви знаєте :)
--include "*.txt" --include "*.TXT"
Також:
find ./ -type f -print0 | xargs -0 grep "foo"
але grep -r
це краща відповідь.
find . -type f -exec grep "foo" '{}' \;
добре працює там, де підтримується.
find ./ -type f -print0 | xargs -0 grep "foo"
Зараз я завжди використовую (навіть у Windows з GoW - Gnu в Windows ):
grep --include="*.xxx" -nRHI "my Text to grep" *
Це включає наступні варіанти:
--include=PATTERN
Повторюйте в каталогах лише пошук відповідності файлів
PATTERN
.
-n, --line-number
Префікс кожного рядка виводу з номером рядка у вхідному файлі.
(Примітка: phuclv додає в коментарях, що -n
значно знижує продуктивність , тому ви можете пропустити цю опцію)
-R, -r, --recursive
Читати всі файли в кожному каталозі, рекурсивно; це рівнозначно
-d recurse
варіанту.
-H, --with-filename
Роздрукуйте назву файлу для кожного матчу.
-I
Обробляйте двійковий файл так, ніби він не містить відповідних даних;
це рівнозначно--binary-files=without-match
варіанту.
І я можу додати " i
" ( -nRHIi
), якщо хочу результати, що не залежать від регістру.
Я можу дістати:
/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43: 'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21: $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32: $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20: protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170: * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176: return $this->hidden;
...
-R
опцію) до папок.
*
або .
це глобальний зразок (інтерпретується оболонкою): unix.stackexchange.com/a/64695/7490 . ' .
' також вибере точкові файли або папки з крапками (як .git/
)
grep -rnI
але потім я дізнався, що -n
значно знижує продуктивність, тому я просто використовую її, коли це дійсно потрібно, і зазвичай я буду користуватися-rI
В системах POSIX ви не знайдете -r
параметр для grep
і grep -rn "stuff" .
не запуститься, але якщо використовувати find
команду, це:
find . -type f -exec grep -n "stuff" {} \; -print
Погоджено Solaris
та HP-UX
.
-exec
варіанті - символ {}
- це посилання на ім'я файлу, яке зараз знайдено find
інструментом (тобто зробити щось із знайденим нами ім'ям файлу), також -exec
опцію слід припинити ;
символом (щоб позначити закінчення команд виконувати), але тому, що це все Запуск у оболонці цього символу слід уникати .. і нарешті -print
опція дозволяє find
інструменту друкувати знайдені імена файлів на екрані.
**
Використання grep -r
робіт, але це може бути надмірним, особливо у великих папках.
Для більш практичного використання ось синтаксис, який використовує синтаксис глобалізації ( **
):
grep "texthere" **/*.txt
який збирає лише певні файли з обраним малюнком. Він працює для підтримуваних оболонок, таких як Bash +4 або zsh .
Щоб активувати цю функцію, виконайте команду: shopt -s globstar
.
Дивіться також: Як знайти всі файли, що містять певний текст в Linux?
git grep
Для проектів під контролем версій Git використовуйте:
git grep "pattern"
що набагато швидше.
ripgrep
Для більш великих проектів найшвидший інструмент прихватування - це те, ripgrep
що файли файлів репресивно за замовчуванням:
rg "pattern" .
Він побудований на базі регекс-двигуна Руста, який використовує кінцеві автомати, SIMD та агресивні буквальні оптимізації, щоб зробити пошук дуже швидким. Перевірте детальний аналіз тут .
Щоб знайти ім'я files
з path
рекурсивно містить конкретну string
команду нижче, використовуйте для UNIX
:
find . | xargs grep "searched-string"
для Linux
:
grep -r "searched-string" .
знайти файл на UNIX
сервері
find . -type f -name file_name
знайти файл на сервері LINUX
find . -name file_name
просто імена файлів теж можуть бути корисними
grep -r -l "foo" .
Якщо ви хочете лише переглядати фактичні каталоги, а не символічні посилання,
grep -r "thingToBeFound" directory
Якщо ви хочете переходити як до символьних посилань, так і до фактичних каталогів (будьте уважні до нескінченної рекурсії),
grep -R "thing to be found" directory
Оскільки ви намагаєтесь рекурсивно відстукувати, наступні варіанти також можуть бути корисними для вас:
-H: outputs the filename with the line
-n: outputs the line number in the file
Отже, якщо ви хочете знайти всі файли, що містять Darth Vader, у поточному каталозі чи будь-яких підкаталогах та захопити ім'я файлу та номер рядка, але не хочете, щоб рекурсія переходила до символічних посилань, команда буде
grep -rnH "Darth Vader" .
Якщо ви хочете знайти в каталозі всі згадки про слово кішка
/home/adam/Desktop/TomAndJerry
і ви зараз в каталозі
/home/adam/Desktop/WorldDominationPlot
і ви хочете захопити ім'я файлу, але не номер рядка будь-якого екземпляра рядка "cats", і ви хочете, щоб рекурсія переходила до символічних посилань, якщо вона їх знайде, ви можете запустити будь-яке з наведених нижче
grep -RH "cats" ../TomAndJerry #relative directory
grep -RH "cats" /home/adam/Desktop/TomAndJerry #absolute directory
Джерело:
працює "grep --help"
Короткий вступ до символічних посилань, для тих, хто читає цю відповідь та збентежений моїм посиланням на них: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
ag - це мій улюблений спосіб зробити це зараз github.com/ggreer/the_silver_searcher . Це в основному те саме, що і ack, але з кількома оптимізаціями.
Ось короткий орієнтир. Я очищаю кеш перед кожним тестом (див. Https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache )
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
Якщо ви шукаєте певний вміст у всіх файлах із структури каталогу, ви можете використовувати, find
оскільки зрозуміліше, що ви робите:
find -type f -exec grep -l "texthere" {} +
Зауважте, що -l
(в нижньому регістрі L) відображається назва файлу, який містить текст. Видаліть його, якщо натомість хочете роздрукувати сам збіг. Або скористайтеся, -H
щоб отримати файл разом із збігом. Всі разом, інші альтернативи:
find -type f -exec grep -Hn "texthere" {} +
Де -n
друкується номер рядка
find
рішенням як уникнути непотрібних використання xargs
і використовувати +
замість \;
з -exec
, тим самим уникаючи тонни непотрібних запусків процесу. :-)
Це той, хто працював у моєму випадку на моїй поточній машині (git bash на Windows 7):
find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
Я завжди забуваю -принт0 і -0 для шляхів з пробілами.
EDIT: Мій улюблений інструмент зараз замість ripgrep: https://github.com/BurntSushi/ripgrep/releases . Це дійсно швидко і має кращі значення за замовчуванням (наприклад, рекурсивні за замовчуванням). Такий же приклад, як і моя оригінальна відповідь, але з використанням ripgrep:rg -g "*.cs" "content pattern"
grep -r "texthere" .
(термін повідомлення наприкінці)
(^ кредит: https://stackoverflow.com/a/1987928/1438029 )
Пояснення:
grep -r "texthere" /
(рекурсивно знімайте всі каталоги та підкаталоги)
grep -r "texthere" .
(рекурсивно знімайте ці каталоги та підкаталоги)
grep [options] PATTERN [FILE...]
[параметри]
-R, -r, --recursive
Читайте всі файли в кожному каталозі, рекурсивно.
Це еквівалентно варіанту
-d recurse
або--directories=recurse
.
$ grep --help
$ grep --help |grep recursive
-r, --recursive like --directories=recurse
-R, --dereference-recursive
ack
( http://beyondgrep.com/ )
У 2018 році ви хочете використовувати ripgrep
або the-silver-searcher
тому, що вони набагато швидші за альтернативи.
Ось каталог із 336 підкаталогами першого рівня:
% find . -maxdepth 1 -type d | wc -l
336
% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py' 1.24s user 2.23s system 283% cpu 1.222 total
% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$' 2.71s user 1.55s system 116% cpu 3.651 total
% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py' 1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs 6.65s user 0.49s system 32% cpu 22.164 total
На OSX, це встановлює ripgrep
: brew install ripgrep
. Це встановлює silver-searcher
: brew install the_silver_searcher
.
rg
вона має значну перевагу над обмотуванням разом рекурсивної команди grep з нуля. Використання rg
: rg foo
. Використання інструментів Unix: find . | xargs grep foo
. І якщо в будь-якому з ваших файлів є цитата, вам потрібно скористатися find . -print0 | xargs -0 grep foo
. Чи пам’ятаєте ви про це, якщо користуєтесь цим кілька разів на рік?
find . -type f -exec grep 'regex' {} +
що насправді легко запам'ятати, якщо ви використовуєте ці інструменти з будь-якою регулярністю. Але, мабуть, вам слід все-таки запуститись ctags
або etags
на вихідному дереві, якщо вам потрібно часто знаходити матеріали.
У моєму сервері IBM AIX (версія ОС: AIX 5.2) використовуйте:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
це дозволить роздрукувати шлях / ім'я файлу та відносний номер рядка у файлі, як:
./inc/xxxx_x.h
2865: / ** Опис: stringYouWannaFind * /
все одно, це працює для мене:)
Нижче наведено команду для пошуку String
рекурсивно в середовищі Unix
та Linux
оточенні.
для UNIX
команди є:
find . -name "string to be searched" -exec grep "text" "{}" \;
для Linux
команди є:
grep -r "string to be searched" .
Список доступних прапорів:
grep --help
Повертає всі збіги для текстового поля регулярного виразів у поточному каталозі з відповідним номером рядка:
grep -rn "texthere" .
Повертає всі збіги для texthere , починаючи з кореневого каталогу, з відповідним номером рядка та ігноруючи регістр:
grep -rni "texthere" /
тут використовуються прапори:
-r
рекурсивний -n
номер рядка для друку з виходом -i
ігнорувати випадокЯ думаю, це те, що ти намагаєшся написати
grep myText $(find .)
і це може бути чим-небудь корисним, якщо ви хочете знайти файли під час перегляду
grep myText $(find .) | cut -d : -f 1 | sort | uniq
Зауважте, що find . -type f | xargs grep whatever
різноманітні рішення потраплятимуть до помилок "Список аргументів на довгі", коли занадто багато файлів, які відповідають пошуку.
Найкраща ставка, grep -r
але якщо такої немає, скористайтеся find . -type f -exec grep -H whatever {} \;
натомість.
xargs
конкретно вирішує проблему "Аргумент надто довгий".
find . -type f | xargs -L 100 grep whatever
xargs
стандартизований для виведення такої поведінки поза коробкою. " xargs
Утиліта повинна обмежувати довжину командного рядка таким чином, що коли викликається командний рядок, комбіновані списки аргументів та середовища ... не повинні перевищувати {ARG_MAX} -2048 байт."
Ось рекурсивна (злегка перевірена з bash та sh) функція, яка обходить всі папки в заданій папці ($ 1) та використовує grep
пошук по заданому рядку ($ 3) у заданих файлах ($ 2):
$ cat script.sh
#!/bin/sh
cd "$1"
loop () {
for i in *
do
if [ -d "$i" ]
then
# echo entering "$i"
cd "$i"
loop "$1" "$2"
fi
done
if [ -f "$1" ]
then
grep -l "$2" "$PWD/$1"
fi
cd ..
}
loop "$2" "$3"
Запуск його та приклад виводу:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename