Bash: есть ли способ поиска определенной строки в каталоге файлов? [Дубликат]


47

Возможное дублирование:
поиск текстового шаблона в linux

В bash мне было интересно, есть ли какие-нибудь команды, которые позволят вам узнать, существует ли конкретная искомая строка в файлах, находящихся в текущем каталоге, в котором вы находитесь.

Скажем, вы ищете функцию toUpperCase () в наборе файлов C в вашем текущем каталоге. Существует множество файлов, поэтому вам не нужно открывать каждый из них вручную с помощью vim и проверять строку «toUpperCase», потому что это займет много времени. Если не командная строка bash, есть ли другой способ сделать это эффективно?

Ответы:


64

С grep:

grep -R "toUppercase()" *

Или, если у вас установлен ack-grep , просто:

ack-grep "toUppercase"

Если вы хотите ограничить поиск в файлах C, с помощью ack-grep:

ack-grep -cc "toUppercase()"

ack-grepтакже может быть установлен на OSX, но исполняемый файл называется просто ack.


Настолько, что у SO уже есть подозрительно похожий вопрос ;)
Дэвид Перри

10

Стандартный инструмент поиска текста - grep .

Чтобы найти строку toUpperCase(во всех .cфайлах в текущем каталоге:

grep -F 'toUpperCase(' *.c

Если вы хотите посмотреть и в подкаталогах:

grep -r --include='*.c' -F 'toUpperCase('

Если вы ищете вызовы функций C, тогда ctags может подойти лучше. Вы запускаете его один раз для всех своих исходных файлов, чтобы создать индекс идентификаторов, а затем используете свой редактор для навигации между вызовами. Все редакторы, похожие на vi, могут использовать TAGSфайл ctags . Если вы используете Emacs, запустите аналогичную программу etags.


ctagsполезно для поиска определений функций , а не вызовов функций .
JdeBP

6

Вы используете Vim. У вас есть инструмент для этого встроен.

Как и ожидалось, есть семь ответов, которые уже говорят, чтобы использовать grep. Но я, кажется, пока единственный человек, который заметил по вашему вопросу, что вы используете vim. Таким образом, хотя вы можете использовать grepизнутри vim, вы также можете использовать vimвстроенный инструмент. Это вызывается с помощью :vimgrepкоманды.

Для поиска «всех исходных файлов C в текущем каталоге для вызовов функции toUpperCase()» введите vimкоманду

:vimgrep "\<toUpperCase\_s*(" *.c

Результирующий список совпадений автоматически загружается в список быстрых исправлений, доступный любому из них (см. Интерактивную справку для тонкой разницы)

:copen
:cwin

Чтобы найти определение функции , а не вызовы к ней, ctagsэто инструмент, как упоминалось в Gillesответе , в сочетании с командами :tjumpили :tselect.

Зачем использовать :vimgrep?

Он-лайн help ( :help grep) перечисляет несколько причин, которые я не буду здесь описывать. В дополнение к тем, сравнить действие :vimgrepс этим в dietbuddhaответ «S . dietbuddhaКомандная строка разветвляет отдельный grepпроцесс для каждого отдельного исходного файла Си. Это даже не использует, xargsчтобы уменьшить эти накладные расходы. И вам все равно придется как-то анализировать выходные данные, чтобы вызвать ваш текстовый редактор в соответствующих исходных файлах после его завершения. :vimgrepне разветвляется на несколько дополнительных процессов, а использование результата само по себе просто. При простом выборе одной из записей в результирующем списке быстрых исправлений курсор автоматически помещается на соответствующую строку соответствующего исходного файла.

На самом деле, он делает именно то, что вы написали, вы бы делали вручную, кроме как автоматически. Это автоматизированный способ выполнения тех же самых действий текстового редактора. Он загружает файл, как если бы он был загружен вручную, ищет в нем регулярное выражение (используя тот же синтаксис регулярного выражения, который вы уже использовали в другом месте vim), записывает места, где происходят совпадения, а затем выгружает файл.


2

Да, инструмент называется grep.

Команда grep ищет в одном или нескольких входных файлах строки, содержащие соответствие указанному шаблону. По умолчанию grep печатает совпадающие строки.

Основное использование:

grep something somewhere

Или, более конкретно:

grep [some options] pattern file

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

grep -ri "touppercase()" .

Если вы хотите только соответствующие части, используйте -oопцию.

Grep может использовать регулярные выражения , и у него есть огромное руководство .


2

grepстандартный ответ - использование флага -r для рекурсивного поиска или в сочетании с find(обсуждение и примеры в других вопросах на этом сайте, таких как этот )

Мой предпочтительный выбор в последнее время ack. Скорее всего, он не установлен на вашем компьютере, но вы можете установить его с помощью apt-get в Ubuntu или просто загрузить. Ссылки, инструкции и причины, по которым он лучше, чем grep, доступны по адресу http://betterthangrep.com/.


1

find а также grep

find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print

почему не только grep?

grep -r string .будет проходить через весь файл в текущем каталоге. Если у вас есть объектные файлы или другие двоичные файлы, вы можете получить совпадение с двоичными результатами, иначе. мусор. Если в вашем подкаталоге также есть файлы fifo или файлы устройств, это может привести к неизвестным / непреднамеренным последствиям.

grep string *.cищет только текущие .cфайлы каталогов .

grep string **/*.c выполняет поиск по всем подкаталогам. Однако, если у вас очень большое количество .cфайлов, вы рискуете превысить максимальное количество расширений для оболочки. Расширение также должно произойти в первую очередь, что означает полный обход дерева перед началом grep.


0

Grep добьется цели, но немного дополнительных сценариев поможет найти имя файла и точную строку, на которую он ссылается. Если это то, что вы хотите, я считаю, что следующее работает хорошо. Я сохранил его как сценарий оболочки и передал ему нужное значение в качестве первого параметра командной строки.

for i in $(ls)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?
    if [ $STATUS  -eq 0 ] ; then
        echo $i
        cat $i | grep -n $1
    fi
done

3
У grep есть опция -H, которая делает это уже. grep -Что угодно *
Рой Рико

Узнайте что-то новое каждый день .. Спасибо @ Рой Рико
Тим Бригам

0

Мне интересно, что никто не ответил на ваш конкретный вопрос: «Как мне найти, существует ли конкретная строка в файлах, находящихся в текущем каталоге». Насколько я знаю, нет никакой опции grep, которая только возвращает, было ли найдено совпадение в группе файлов. Ближайшая опция -l, чтобы вывести список имен файлов. Ближайший ответ среди тех, кто пока что дал Тим, с небольшими изменениями:

#!/usr/bin/bash

for i in $(ls *.c 2> /dev/null)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?

    if [ $STATUS  -eq 0 ] ; then
        echo "Found"
        exit
    fi
done

echo "Not found"

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

Дуг

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.