Как я могу открыть файл, полученный в результате grep?

17

Я часто grep кучу файлов, чтобы найти строку, а затем grep возвращает один результат. Вместо того, чтобы копировать и вставлять имя файла в новую команду, я хотел бы иметь возможность открыть этот результат с помощью редактора. Что - то вроде: grep foo | vim. Есть ли способ сделать это в BASH?

Джонатан
источник
5
Вы были довольно близки, просто скажи, vimчтобы читать с STDIN:grep foo | vim -
devnull
2
См. Также unix.stackexchange.com/q/110146/22565
Стефан

Ответы:

20

Используйте, grep -lчтобы просто получить имя файла соответствующего файла, а не соответствующий текст, а затем объединить его с vim:

vim "$(grep -l some_pattern file_names)"
Энтон
источник
Кроме того, вы можете использовать -qфлаг of, grepчтобы убедиться, что grep действительно привел к некоторому соответствующему файлу:grep -q patterns fnames && vim $(grep -l pattern fnames)
mkc
Должен ли я сделать замечание по поводу имен файлов с пробелами?
Бернхард
@Bernhard Это никогда не повредит, а также о тех, кто с переводами строки и другими специальными символами. Я узнаю проблему, когда viжалуюсь, ОП не может.
Anthon
Не работает, если у совпадающих файлов есть пробелы в пути
psuzzi
5

Вы можете использовать quickfixили использовать errorfileв vim:

$ grep -n foo * > /tmp/foo.list
$ vim -q /tmp/foo.list

Vim откроет первый файл /tmp/foo.listи поместит курсор прямо в строку, где fooбыл найден. Вы можете перейти к следующему экземпляру, используя :cnи предыдущий экземпляр, используя :cp.

Примечание : если вы уже используете vimили gvim, то я бы предложил использовать встроенные grepфункции. Читайте :help vimgrepдля получения дополнительной информации.

Srinidhi
источник
1

Для поиска в проекте не нужно оставлять vim с Fugitive

autocmd QuickFixCmdPost *grep* cwindow

Ниже вы можете увидеть пример :Ggrep config

введите описание изображения здесь

goodniceweb
источник
0

РЕДАКТИРОВАТЬ: После прочтения вашего комментария, я понимаю, что изначально я не понял вопрос. Вот простой скрипт, который принимает ваш поисковый термин в качестве аргумента и запрашивает путь для поиска. Если результат найден только в одном файле, он открывает файл для редактирования в том месте, где находится результат поиска.

#!/bin/bash

SRCHTRM="$1"

read -p "Where to search: " SRCHPATH

FILEFOUND=$(grep "$SRCHTRM" $SRCHPATH)
FILEFOUNDCNT=$(grep "$SRCHTRM" $SRCHPATH | wc -l)

FILEAWK=$(echo "$FILEFOUND" | awk -F":" '{ print $1 }')

if [ "$FILEFOUNDCNT" -eq "1" ];then
    vi +/"$SRCHTRM" "$FILEAWK"
else
    echo "$1 was found in more than one file"
fi
Тимоти Мартин
источник
Но это, кажется, позволяет мне редактировать вывод grep, но я хочу отредактировать файл с именем файла, которое возвращает grep.
Джонатан
0

@devnull получил ответ прямо в этом комментарии:

Вы были довольно близки, просто скажите vim читать из STDIN:

grep foo | vim -

Ноумен
источник
0

Чтобы расширить ответ Anthon для случая, когда у вас более одного совпадения, в некоторых случаях может быть полезно использовать head -1(из этого ответа ) выбор только первого результата:vim "$(grep -l STRING FILES|head -1)"

EL_DON
источник
0

Если вы выполняете длинную команду, где где-то посередине есть grep, вы также можете выполнить

vim `command1 | grep whatever | awk '{do_something_else}'`
Greg
источник