Як знайти всі файли, що містять певний текст у Linux?


5254

Я намагаюся знайти спосіб сканувати всю мою систему Linux на всі файли, що містять певний рядок тексту. Просто для уточнення, я шукаю текст у файлі, а не у назві файлу.

Коли я шукав, як це зробити, я натрапив на це рішення двічі:

find / -type f -exec grep -H 'text-to-find-here' {} \;

Однак це не працює. Здається, відображається кожен окремий файл у системі.

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


21
пам’ятайте, що греп буде інтерпретувати будь-яке .як символічний знак, що складається з одного символу. Моя порада - завжди використовувати або fgrep, або egrep.
Вальтер Трос

10
все одно, ви майже були там! Просто замініть -Hна -l(а може, grepна fgrep). Щоб виключити файли з певними шаблонами імен, ви б використовували findбільш досконалий спосіб. Хоча варто навчитися користуватися find, хоча. Просто man find.
Уолтер Трос

6
find … -exec <cmd> +легше набирати та швидше, ніж find … -exec <cmd> \;. Він працює, лише якщо <cmd>приймає будь-яку кількість аргументів імені файлу. Економія часу на виконання особливо велика, якщо <cmd>почати повільно, як сценарії Python або Ruby.
hagello

Для нерекурсивного пошуку в заданому шляху командою є `grep --include = *. Txt -snw" pattern "thepath / *.
Стефан Лоран

@ StéphaneLaurent Я думаю, ти занадто сильно ускладнюєш це. Просто скажітьgrep "pattern" path/*.txt
fedorqui 'ТАК перестаньте шкодити'

Відповіді:


9511

Зробіть наступне:

grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -rабо -Rє рекурсивним,
  • -n - номер рядка та
  • -w означає, що відповідає цілому слову.
  • -l (малі L) можна додати, щоб просто вказати ім'я файлу відповідних файлів.

Поряд з цим, --exclude, --include, --exclude-dirпрапори можуть бути використані для ефективного пошуку:

  • Це буде шукати лише ті файли, які мають розширення .c або .h:

    grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
    
  • Це виключить пошук усіх файлів, що закінчуються розширенням .o:

    grep --exclude=*.o -rnw '/path/to/somewhere/' -e "pattern"
    
  • Для каталогів можна виключити певний каталог (и) через --exclude-dirпараметр. Наприклад, це виключить dirs dir1 /, dir2 / і всі вони відповідають * .dst /:

    grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
    

Це дуже добре працює для мене, щоб досягти майже такої ж мети, як і ваша.

Для отримання додаткових варіантів перевірити man grep.


74
використання --виключити. як "grep -rnw --exclude = *. o 'каталог' -e" pattern "
rakib_

98
Варто зауважити: здається, що rваріант лінивий (переходить глибину по-перше, ніж зупиняється після першого каталогу), а Rжадібний (буде правильно перетинати все дерево).
Еліран Малька

5
grep -rnw "Рядок, який я шукав" зробив те, що мені потрібно. Дякую!
ViliusK

33
Примітка (особливо для новачків): лапки в наведеній вище команді важливі.
madD7

69
@Eliran Malka Ren rбуде обидва переходити каталоги правильно, але Rбуде переходити до символічних посилань.
bzeaman

1497

Ви можете використовувати grep -ilR:

grep -Ril "text-to-find-here" /
  • i розшифровується як випадок ігнорування (необов’язково у вашому випадку).
  • R означає рекурсивний.
  • l означає "показати ім'я файлу, а не сам результат".
  • / означає починати з кореня вашої машини.

85
Виходячи з мого досвіду, це -iробить його дуже сповільненим, тому не використовуйте його, якщо не потрібно. Перевірте його в певному режимі, а потім узагальнюйте. Його слід завершити протягом декількох хвилин. Я думаю, що регулярний вираз зробив би це повільніше. Але мої коментарі ґрунтуються на припущеннях, я пропоную вам перевірити це timeперед рядком.
fedorqui 'ТАК перестаньте шкодити'

4
Так, /*означає. У будь-якому випадку я просто перевірив це і помітив, що він просто /працює.
fedorqui 'ТАК перестаньте шкодити'

10
Якщо ви не здійснюєте пошук за допомогою регулярного вираження, ви можете використовувати fgrep замість grep у більшості систем.
markle976

8
Так @ markle976, насправді від man grep : fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings.
fedorqui 'ТАК перестаньте шкодити'

17
Ви можете замінити / з шляхом до каталогу grep -Ril "text-to-find-here" ~/sites/або використовувати. для поточного каталогуgrep -Ril "text-to-find-here" .
Чорний

329

Ви можете використовувати ack . Це як греп для вихідного коду. Ви можете сканувати з ним всю вашу файлову систему.

Просто зробіть:

ack 'text-to-find-here'

У вашому кореневому каталозі.

Ви також можете використовувати регулярні вирази , вказувати тип файлу тощо.


ОНОВЛЕННЯ

Щойно я виявив The Silver Searcher , який схожий на ack, але в 3-5 разів швидший за нього і навіть ігнорує зразки з .gitignoreфайлу.


57
Дуже корисно, просто і швидко. Попередження: "У дистрибутивах, отриманих від Debian, ack упаковується як" ack-grep ", оскільки" ack "вже існував" (з сайту vangrep.com/install ). Ви, можливо, запустите конвертер код Kanji на цих Linuxes ...
Jose_GD

11
ack or ack-grep має гарні моменти, але знайти + grep при правильному використанні набагато краще за продуктивністю
Sławomir Lenart

14
Зауважте, що різання швидше, ніж усе інше, що згадується тут, включаючи The Silver Searcher та звичайний 'ol grep. Дивіться цю публікацію в блозі для підтвердження
Радон Росборо

194

Ви можете використовувати:

grep -r "string to be searched"  /path/to/dir

rЧи означає рекурсивні і так буде шукати шляхи , зазначені , а також його підкаталоги. Це покаже вам ім'я файлу, а також роздрукує рядок у файлі, де відображається рядок.

Або команда, аналогічна тій, яку ви намагаєтесь (приклад:) для пошуку у всіх файлах javascript (* .js):

find . -name '*.js' -exec grep -i 'string to search for' {} \; -print

Це надрукує рядки у файлах, де відображається текст, але воно не надрукує ім'я файлу.

Крім цієї команди, ми можемо написати і це: grep -rn "Рядок для пошуку" / шлях / до / каталогу / або / файл -r: рекурсивний пошук n: номер рядка буде показаний для збігів


1
Дякуємо за версію пошуку. У моїй греп-версії (зайнятий для NAS) немає варіанту -r, мені дуже потрібно було інше рішення!
jc

3
Дякую за версію "знайти"! Настільки важливо мати можливість фільтрувати за ' .js' або ' .txt' і т. Д. Ніхто не хоче витрачати години на очікування grep, щоб закінчити пошук усіх багатогігабайтних відеозаписів з останнього сімейного відпустки, навіть якщо команда простіше набрати.
Могутній

краще греп, ніж прийнята версія, тому що прийняті не шукайте
півслов

114

Ви можете скористатися цим:

grep -inr "Text" folder/to/be/searched/

12
найпростіший, багатослівний, рекурсивний і нечутливий до регістру. пальці вгору.
Франческо Касула

якщо ви додасте -A3 ще краще
albanx

73

Список назв файлів, що містять заданий текст

Перш за все, я вважаю, що ви використовували -Hзамість цього -l. Також ви можете спробувати додати текст всередину лапок, після чого {} \.

find / -type f -exec grep -l "text-to-find-here" {} \; 

Приклад

Скажімо, ви шукаєте файли, що містять певний текст "Ліцензія Apache" всередині вашого каталогу. Він відображатиме результати, схожі на наведені нижче (вихід буде відрізнятися залежно від вмісту вашого каталогу).

bash-4.1$ find . -type f -exec grep -l "Apache License" {} \; 
./net/java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$ 

Зніміть чутливість до регістру

Навіть якщо ви не використовуєте про такий випадок, як "текст" проти "ТЕКСТ", ви можете використовувати -iперемикач, щоб ігнорувати регістр. Детальнішу інформацію ви можете прочитати тут .

Сподіваюся, що це вам допоможе.


2
Що і робить ця команда: findпройде всі шляхи, які вона знайде, до команди grep -l "text-to-find-here" <file found>". Ви можете додати обмеження до імені файлу, наприклад, find / -iname "*.txt"шукати лише у файлах, ім'я яких закінчується.txt
Mene

1
@ Допоміжний - включив зразок виводу, щоб уникнути плутанини для читачів.
lkamal

2
@Mene Дійсно сумно констатувати, що коментар Допоміжного має більше голосів, ніж ваш ... навіть якщо їх коментар від 2014 року, а ваш - 2017 рік, у їхньому коментарі 6, коли у нього повинно бути рівно 0, а у вашого лише один (зараз два) У те, у що я хотів би повірити.
Прифтан

@Mene Це, як говориться -iname, нечутливе до регістру, що означає, що він також знайде файли .TXT, наприклад, а також TxT і TXt тощо.
Прифтан

66

grep( GNU або BSD )

Ви можете використовувати grepінструмент для рекурсивного пошуку поточної папки, наприклад:

grep -r "class foo" .

Примітка: -r- Рекурсивно шукати підкаталоги.

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

grep "class foo" **/*.c

Примітка: Використовуючи параметр globbing ( **), він сканує всі файли рекурсивно з певним розширенням або шаблоном. Щоб включити цей синтаксис, виконайте наступну команду: shopt -s globstar. Ви також можете використовувати **/*.*для всіх файлів (крім прихованого та без розширення) або будь-якого іншого шаблону.

Якщо ви маєте помилку, що ваш аргумент занадто довгий, подумайте про звуження пошуку або findзамість цього використовуйте синтаксис, наприклад:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

Альтернативно використовувати ripgrep.

ripgrep

Якщо ви працюєте над більшими проектами або великими файлами, вам слід скористатися на ripgrepзразок:

rg "class foo" .

Ознайомтеся з документами, етапами встановлення або вихідним кодом на сторінці проекту GitHub .

Це набагато швидше , ніж будь-який інший інструмент , як GNU / BSD grep , ucg, ag, sift, ack, ptабо подібне, так як він побудований на вершині регулярних виразів Руста , який використовує кінцеві автомати, SIMD і агресивні літерні оптимізації , щоб зробити пошук дуже швидко.

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


Ви можете використовувати загальні параметри, такі як:

  • -i - Нечутливий пошук.
  • -I - Ігноруйте двійкові файли.
  • -w - Пошук цілих слів (на противагу частковому зіставленню слів).
  • -n - Покажіть лінію вашої відповідності.
  • -C/ --context(наприклад -C5) - збільшує контекст, тому ви бачите навколишній код.
  • --color=auto - Позначте відповідний текст.
  • -H - Відображає ім'я файлу, де знаходиться текст.
  • -c- Відображає кількість відповідних ліній. Можна комбінувати з -H.

1
Я також вважаю корисним розширений глобус. Але майте на увазі, що якщо дійсно величезна кількість файлів, ви можете отримати помилку "Аргумент занадто довгий". (Простий глобус також схильний до подібних помилок).
Yoory N.

2
Для вдихання всієї файлової системи rg буде набагато менш болючим, ніж майже будь-який інший інструмент.
lk

55

Якщо ваш grepне підтримує рекурсивний пошук, ви можете комбінувати його findз xargs:

find / -type f | xargs grep 'text-to-find-here'

Мені це легше запам’ятати, ніж формат для find -exec.

Це виведе ім'я файлу та вміст відповідного рядка, наприклад

/home/rob/file:text-to-find-here

Необов’язкові прапори, які ви можете додати до grep:

  • -i - нечутливий пошук у випадку
  • -l - вивести лише ім'я файлу, де було знайдено збіг
  • -h - виводити лише відповідний рядок (не ім'я файлу)

3
Це еквівалентно grep 'text-to-find-here'без імені файлу, якщо findнічого не знаходить. Це зависне і чекатиме введення користувача! Додати --no-run-if-emptyяк опцію в xargs.
hagello

3
Ця комбінація знаходження і xargs не працює за призначенням, якщо імена файлів або каталогів містять пробіли (символи, які xargs інтерпретує як роздільники). Використовуйте find … -exec grep … +. Якщо ви наполягаєте на використанні пошуку разом із xargs, використовуйте -print0та -0.
hagello

43
grep -insr "pattern" *
  • i: Ігноруйте відмінність регістру і в PATTERN, і у вхідних файлах.
  • n: Префікс кожного рядка виводу з номером рядка на основі 1 у вхідному файлі.
  • s: Придушення повідомлень про помилки щодо неіснуючих чи нечитабельних файлів.
  • r: Читайте всі файли в кожному каталозі, рекурсивно.

3
Чи можете ви пояснити, як ваша відповідь покращується на інші відповіді, чи наскільки вона досить відрізняється від них?
Амос М. Карпентер

не дуже складний для запам'ятовування, буде охоплювати всі шаблони (чутливість до регістру -> вимкнено, включає в себе імена файлів та номер рядка та буде робити рекурсивний пошук і т. д.) і, використовуючи "*", врешті решт шукатиме всі каталоги (не потрібно вказувати жодних шлях або ім'я каталогу).
enfinet

Вибачте, я мав би бути зрозумілішим: було б чудово, якби ви включили це пояснення у свою відповідь. Як відомо, особливо з такою кількістю інших подібних відповідей, важко зрозуміти з такої короткої відповіді, яка користь буде спробувати її над прийнятою відповіддю чи однією з схвалених.
Амос М. Карпентер

6
@ AmosM.Carpenter Одне, що мені подобається у цій відповіді, - це вказати аргумент придушення, який може допомогти відфільтрувати шум, який не має значення для отримання результатів, які ми насправді бажаємо. Grep друкує помилки типу "Функція не реалізована", "Недійсний аргумент", "Ресурс недоступний" тощо тощо на певні "файли".
leetNightshade

@leetNightshade: Я припускаю, що ти звертаєшся до свого коментаря до мене, тому що я попросив пояснення щодо рідкої оригінальної публікації. Будь ласка, дивіться чудову редакцію Фабіо щодо моїх попередніх коментарів, щоб мати сенс.
Амос М. Карпентер

39

Існує нова утиліта під назвою The Silversearcher

sudo apt install silversearcher-ag

Він тісно співпрацює з Git та іншими VCS. Таким чином, ви не отримаєте нічого в .git або іншому каталозі.

Ви можете просто використовувати

ag "Search query"

І це зробить завдання для вас!


35

Як знайти всі файли, що містять певний текст у Linux? (...)

Я натрапив на це рішення двічі:

find / -type f -exec grep -H 'text-to-find-here' {} \;


Якщо ви використовуєте find як у вашому прикладі, краще додайте -s( --no-messages) до grepта 2>/dev/nullв кінці команди, щоб уникнути безлічі повідомлень, відхилених у дозволі, виданих grepта find:

find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null

find - це стандартний інструмент пошуку файлів - у поєднанні з grep при пошуку конкретного тексту - на платформах, схожих на Unix. Команда find часто поєднується з xargs , до речі.

Для тієї ж мети існують швидші та простіші інструменти - див. Нижче. Краще спробуйте , звичайно , якщо вони доступні на вашій платформі :

Швидші та легші альтернативи

RipGrep - найшвидший інструмент пошуку навколо:

rg 'text-to-find-here' / -l

Пошук срібла :

ag 'text-to-find-here' / -l

ack :

ack 'text-to-find-here' / -l

Примітка. До 2>/dev/nullцих команд можна також додати , щоб приховати багато повідомлень про помилки.


Попередження : якщо ви дійсно не можете цього уникнути, не шукайте з '/' (кореневої директорії), щоб уникнути тривалого та неефективного пошуку! Тож у наведених вище прикладах краще замінити ' / ' на ім’я підкаталогу, наприклад, "/ home" залежно від того, де ви насправді хочете шукати ...


"find - це стандартний інструмент пошуку файлів, що містять конкретний текст на платформах, схожих на Unix" , мені здається досить неоднозначним. Навіть крім того, рекурсивний grep findне шукає безпосередньо текст всередині файлів. І, можливо, ці додаткові інструменти будуть корисні для деяких, але старих таймерів, а ті, до кого добре звикли, наприклад, grepвзагалі не давали б їм часу (ну я точно не буду). Не кажучи, що вони марні.
Прифтан

".... що містить конкретний текст ...": ця частина речення була неточною (тому що саме ця частина пошуку не стосується). Відредаговано. Дякую.
Bludzee

Радий допомогти! Єдине, що дуже швидко виглядає - це зміна папки слів у каталог, але я знаю, що це мій хрестовий похід, який я ніколи не виграю повністю. Не
здаючись,

Чому б не "каталог" замість "папки", а чому? Будь ласка, поділіться своїм "хрестовим походом"!
Bludzee

Я кажу, що замість цього використовувати каталог! Посилаючись на: вам краще замінити "/" на ім'я підпапки. І це мій пташиний улюбленець .. esp, оскільки навіть Windows раніше його називали "каталогом". Ах ... можливо, ти це отримав. Чому? Ну тому, що це так називається. Це також називається на рівні файлової системи. І погляньте на це так: чи колись його називали (для DOS) fol? Ні, звичайно, ні; його називали dir(і я вважаю, що все ще є). Папка - це річ, надумана для (припускаю) зручності для користувачів, хоча в цьому випадку це, можливо, скидає її на менш "просунутих" користувачів?
Прифтан

29

Спробуйте:

find . -name "*.txt" | xargs grep -i "text_pattern"

5
Це насправді чудовий приклад того, коли НЕ використовувати xargsподібне .. врахуйте це. echo "file bar.txt has bar" > bar.txt; echo "file foo bar.txt has foo bar" > "foo bar.txt"; echo "You should never see this foo" > foo; find . -name "*.txt" | xargs grep -i foo # ./foo:You should never see this foo. xargsТут відповідають не тому файлу і не відповідають наміченому файлу. Або використовуйте, find .. -print0 | xargs -0 ...але це марне використання труби або кращеfind ... -exec grep ... {} +
шалом

29

Використовуйте pwdдля пошуку з будь-якого каталогу, в якому ви перебуваєте, повторюючись вниз

grep -rnw `pwd` -e "pattern"

Оновлення Залежно від версії grep, яку ви використовуєте, ви можете опустити її pwd. Для нових версій, .здається, випадок для grep за замовчуванням, якщо каталог не вказаний таким чином:

grep -rnw -e "pattern"

або

grep -rnw "pattern"

зробить те саме, що вище!


3
використовувати pwdзовсім не потрібно, оскільки це за замовчуванням. grep -rnw "pattern"достатньо.
fedorqui 'ТАК перестаньте шкодити'

а насправді grep -rnwі подібне - це відповідь, як три роки тому, я не бачу, як ця відповідь додає значення.
fedorqui 'ТАК перестаньте шкодити'

Вибрана відповідь не показує схему за замовчуванням, і 5 людей, здавалося, вважають її корисною
mahatmanich

Що ви маєте на увазі під "типовим шаблоном"? Прийнята відповідь містить grep -rnw '/path/to/somewhere/' -e "pattern"те, що ви тут маєте. 5 голосів після 2,3-мільймових візитів - це не так вже й значить.
fedorqui 'ТАК перестаньте шкодити'

Я погоджуюсь :-) те, що мені не вистачало в оригінальній відповіді, - це випадок використання, який вам зовсім не потрібно давати шлях або рекурсивно шукати поточний каталог, що не відображено у прийнятій відповіді. Таким чином, це був хороший досвід навчання грепу копати трохи глибше.
mahatmanich

19

grep може бути використаний, навіть якщо ми не шукаємо рядок.

Просто працює,

grep -RIl "" .

буде надрукувати шлях до всіх текстових файлів, тобто до тих, що містять лише символи для друку.


2
Я не бачу, як це краще, ніж використовувати простий lsабо find(для рекурсивного)
fedorqui 'ТАК перестаньте шкодити'

17

Ось декілька списку команд, за допомогою яких можна шукати файл.

grep "text string to search” directory-path

grep [option] "text string to search” directory-path

grep -r "text string to search” directory-path

grep -r -H "text string to search” directory-path

egrep -R "word-1|word-2” directory-path

egrep -w -R "word-1|word-2” directory-path

5
що це додає до існуючих відповідей?
fedorqui 'ТАК перестаньте шкодити'

@fedorqui egrepрівнозначний, grep -Eі це означає, що --extended-regexpви можете знайти деталі тут unix.stackexchange.com/a/17951/196072
omerhakanbilici

17

Silver Searcher - це надзвичайний інструмент, але рипінг може бути ще кращим.

Він працює в Linux, Mac і Windows, і він був написаний на Hacker News пару місяців тому (тут є посилання на блог Ендрю Галланта, який містить посилання на GitHub):

Ripgrep - новий інструмент пошуку командного рядка


15
find /path -type f -exec grep -l "string" {} \;

Пояснення з коментарів

find - команда, яка дозволяє знаходити файли та інші об'єкти, такі як каталоги та посилання у підкаталогах заданого шляху. Якщо ви не вказали маску, якій повинні відповідати імена файлів, вона перераховує всі об'єкти каталогів.

-type f specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename

15

Спробуйте:

find / -type f -exec grep -H 'text-to-find-here' {} \;

який буде шукати всі файлові системи, тому що /це коренева папка.

Для використання домашньої папки:

find ~/ -type f -exec grep -H 'text-to-find-here' {} \;

Для поточного використання папки:

find ./ -type f -exec grep -H 'text-to-find-here' {} \;

Можливо, подробиці різниць папок для багатьох очевидні ... але також дуже корисні для новачків. +1
nilon

1
що це додає до існуючих відповідей?
fedorqui 'ТАК перестаньте шкодити'

Назвіть це мій хрестовий похід, але слово - «каталог». Це не Windows (яка раніше використовувала "каталог" - до 9x). Будь ласка, перестаньте говорити "папка". Що стосується вашої останньої команди, то вам навіть не потрібен просто FYI.
Прифтан

15

Сподіваюся, це допоможе ...

Розгорнувши grepтрохи, щоб дати більше інформації у висновку, наприклад, щоб отримати номер рядка у файлі, де знаходиться текст, можна зробити так:

find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

І якщо у вас є уявлення про тип файлу, ви можете звузити пошук, вказавши розширення типу файлу для пошуку, в цьому випадку .pasАБО .dfmфайли:

find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"

Коротке пояснення варіантів:

  1. .в findспецифікаціях з поточного каталогу.
  2. -name« *.*»: Для всіх файлів (-name « *.pas» -o -name « *.dfm»): тільки *.pasАБО *.dfmфайли, або вказані з-o
  3. -type f вказує, що ви шукаєте файли
  4. -print0і --nullз іншого боку |(труби) є важливими з них, передаючи ім'я файлу від findдо grepвбудованих в xargs, що дозволяє для проходження імен файлів з пробілами в іменах файлів, що дозволяє Grep ставитися шлях і ім'я файлу , як один рядок, і не розбивати його на кожен пробіл.

-name '*.*'не те, що ти кажеш; він не збирається у файлі під назвою "файл", оскільки шаблон не прирівнюється до цього (немає .ext); *однак (добре. файли вбік). Але є ще одна річ: якщо ви хочете, щоб усі файли, навіщо взагалі турбуватись із зазначенням імені файлу? Жодного іншого коментаря - окрім того, що приємно знати, що все ще є люди, які не використовують термінологічну папку MS (яку насправді після того, як сказати це досить, я б не додав, але хотів би зазначити трохи неправильне твердження, яке ви зробили з іменами файлів - а також надмірність / непотрібність у випадку "всіх".
Прифтан

15

Простий findможе працювати зручно. псевдонім його у вашому ~/.bashrcфайлі:

alias ffind find / -type f | xargs grep

Запустіть новий термінал і видайте:

ffind 'text-to-find-here'

14

Я написав сценарій Python, який робить щось подібне. Ось як слід використовувати цей скрипт.

./sniff.py path pattern_to_search [file_pattern]

Перший аргумент, path- це каталог, в якому ми будемо шукати рекурсивно. Другий аргумент, pattern_to_search- це регулярний вираз, який ми хочемо шукати у файлі. Ми використовуємо звичайний формат виразів, визначений у бібліотеці Python re . У цьому сценарії .також відповідає новому рядку .

Третій аргумент, file_patternнеобов’язковий. Це ще один регулярний вираз, який працює на ім’я файлу. Будуть розглядатися лише ті файли, які відповідають цьому регулярному виразу.

Наприклад, якщо я хочу шукати файли Python з розширенням, pyщо містить Pool(слово Adaptor, я виконую наступне,

./sniff.py . "Pool(.*?Adaptor"  .*py
./Demos/snippets/cubeMeshSigNeur.py:146 
./Demos/snippets/testSigNeur.py:259 
./python/moose/multiscale/core/mumbl.py:206 
./Demos/snippets/multiComptSigNeur.py:268 

І вуаля, він генерує шлях відповідних файлів та номера рядка, за яким було знайдено збіг. Якщо було знайдено більше одного збігу, то до імені файлу додається номер кожного рядка.


14

Якщо ви категорично хочете використовувати, findтоді використовуйте find + grep:

find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;

кроки:

1.Використовуйте findдля пошуку файлів,
2.Запустіть grepна всіх.

Це може дати вам findможливість знаходити файли.

  • Використовуйте, -name Patternякщо потрібно grepлише певні файли:

    find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;

Ви можете грати з ним і використовувати різні варіанти, findщоб поліпшити або звузити пошук файлів.


Яка різниця? Чи буде це працювати з пробілами в шляху файлу?
Пітер Мортенсен

13

Використання:

grep -c Your_Pattern *

Це повідомить, скільки примірників вашого шаблону є у кожному з файлів у поточному каталозі.


13

grep - ваш добрий друг, щоб досягти цього.

grep -r <text_fo_find> <directory>

Якщо вам не байдуже регістр тексту, який потрібно знайти, скористайтеся:

grep -ir <text_to_find> <directory>

У моєму випадку схоже, що він шукає всюди, навіть якщо я вкажу каталог
Pathros,

@Pathros Можливо, це стосується включеної рекурсії та того, який каталог ви вкажете. Інший спосіб рекурсія змінює речі таким чином.
Прифтан

@Pathros О, і якщо -в рядку пошуку є s, ви хочете спочатку перейти --до grep; які можуть викликати цікаві побічні ефекти в іншому випадку!
Прифтан

13

Мене зачаровує, як простий греп робить його з 'rl':

grep -rl 'pattern_to_find' /path/where/to/find

-r to recursively find a file / directory inside directories..
-l to list files matching the 'pattern'

Використовуйте '-r' без 'l', щоб побачити імена файлів з текстом, у якому знайдено шаблон !

grep -r 'pattern_to_find' /path/where/to/find

Це працює просто ідеально ...


Це також працює в Git Bash (Windows).
Пітер Мортенсен

Але це означає, що кожен файл повинен шукати (немає фільтра на ім'я файлу чи розширення файлу, як .txt). Або є спосіб це зробити?
Пітер Мортенсен

12

Щоб шукати рядок та виводити саме цей рядок із рядком пошуку:

for i in $(find /path/of/target/directory -type f); do grep -i "the string to look for" "$i"; done

наприклад:

for i in $(find /usr/share/applications -type f); \
do grep -i "web browser" "$i"; done

Щоб відобразити ім'я файлу, що містить рядок пошуку:

for i in $(find /path/of/target/directory -type f); do if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

наприклад:

for i in $(find /usr/share/applications -type f); \
do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
fi; done;

1
Я бачу лише мінус порівняно з використанням find … -exec grep 'str' {} \;(якщо вам доведеться findвзагалі користуватися).
phk

1
Це жахливо зламається, якщо будь-який з файлів, що знаходяться в findпробілах .. Ви можете виявити greppingпомилкові файли та / або взагалі пропустити потрібні файли. Просто використовуйте, find ... -exec grep ...якщо у вас є потреба використовувати find.. але в цьому випадку grep -r ...достатньо.
шалом

1
який сенс використовувати цикл над результатами знаходження, щоб потім отримати греп? Це стає непотрібно складним.
fedorqui 'ТАК перестаньте шкодити'

12

Є ackінструмент, який би зробив саме те, що ви шукаєте.

http://linux.die.net/man/1/ack

ack -i search_string folder_path/*

Ви можете ігнорувати -iпошук з урахуванням регістру


2
Що це додає до існуючих відповідей? Це було запропоновано вже більше трьох років тому.
fedorqui 'ТАК перестаньте шкодити'

1
@fedorqui 1) жодних трубопроводів! 2) Використовуйте регулярні вирази 3) Отримайте номери рядків, ім'я файлу з відносним шляхом, виділений текст тощо, корисний для редагування після пошуку, наприклад, "vim + lineno path / file.cpp", ви отримаєте прямо на рядку, який не цікавить. Дивіться висновок команди "ack include \ | hpp", що шукає ключові слова "include" або "hpp" в моїй папці пошуку та вкладених папках. Я сподіваюся, що справа зрозуміла. Ось зразок виводу (Неможливо відобразити ключові слова з простим текстом) process / child.hpp 11: boost / process / child.hpp process / all.hpp 21: #include <boost / process / Execute.hpp>
Pal

12

Усі попередні відповіді пропонують отримати греп і знайти. Але є й інший спосіб: використовувати Midnight Commander

Це безкоштовна утиліта (30 років, перевірена часом), яка є візуальною, не будучи GUI. У ньому є безліч функцій, а пошук файлів - лише одна з них.


Рейнджер був би в тій же ідеї
nilon

11

Наведена нижче команда буде добре працювати для цього підходу:

find ./ -name "file_pattern_name"  -exec grep -r "pattern" {} \;

2
в чому сенс використання, findа потім grep -r? Вони призначені для того ж, тому це зайве.
fedorqui 'ТАК перестаньте шкодити'

ой !! виправлено, насправді знайдіть для запуску grep на відфільтрованих файлах, а не на всіх, дякую
Pradeep Goswami

2
все-таки це не має сенсу, за допомогою якого ви можете фільтрувати find.
fedorqui 'SO перестаньте шкодити'

11

Уникайте клопоту і встановлюйте ack-grep. Це усуває багато питань дозволу та котирування.

apt-get install ack-grep

Потім перейдіть до каталогу, який потрібно шукати, і запустіть команду нижче

cd /
ack-grep "find my keyword"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.