Como posso abrir um arquivo que resulta do grep?

17

Costumo grep um monte de arquivos para encontrar uma linha e, em seguida, grep retorna um resultado. Em vez de copiar e colar o nome do arquivo em um novo comando, eu gostaria de poder abrir esse resultado com um editor. Algo como: grep foo | vim. Existe uma maneira de fazer isso no BASH?

Jonathan
fonte
5
Você estava bastante próxima, simplesmente dizer vimpara ler STDIN:grep foo | vim -
devnull
2
Veja também unix.stackexchange.com/q/110146/22565
Stéphane Chazelas

Respostas:

20

Use grep -lapenas para obter o nome do arquivo do arquivo correspondente e não o texto correspondente; em seguida, combine-o com vim:

vim "$(grep -l some_pattern file_names)"
Anthon
fonte
Além disso, você pode usar o -qsinalizador de greppara garantir que o grep tenha realmente resultado em algum arquivo correspondente:grep -q patterns fnames && vim $(grep -l pattern fnames)
mkc
Devo fazer uma observação sobre nomes de arquivos com espaços?
Bernhard
@ Bernhard Ele nunca pode machucar, e também sobre aqueles com novas linhas e outros caracteres especiais. I reconhecer o problema quando vise queixa, o OP talvez não.
Anthon
Não funciona se os arquivos combinados ter espaços em seu caminho
psuzzi
5

Você pode usar quickfixou errorfiledestacar vim:

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

O Vim abrirá o primeiro arquivo /tmp/foo.liste posicionará o cursor diretamente na linha em que foofoi encontrado. Você pode ir para a próxima instância usando :cne a instância anterior usando :cp.

Nota lateral : Se você já estiver usando vimou gvim, sugiro usar sua grepfuncionalidade embutida. Leia :help vimgreppara mais informações.

Srinidhi
fonte
1

Para pesquisar no projeto, não é necessário sair do vim com o Fugitive

autocmd QuickFixCmdPost *grep* cwindow

Abaixo você pode ver um exemplo de :Ggrep config

insira a descrição da imagem aqui

goodniceweb
fonte
0

EDIT: Depois de ler seu comentário, percebo que não entendi a pergunta inicialmente. Aqui está um script simples que usa seu termo de pesquisa como argumento e solicita o caminho a ser pesquisado. Se o resultado for encontrado em apenas um arquivo, ele abrirá o arquivo para edição no local do resultado da pesquisa.

#!/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
Timothy Martin
fonte
Mas isso parece me permitir editar a saída do grep, mas o que eu quero fazer é editar o arquivo com o nome do arquivo que o grep retorna.
21414 Jonathan
0

@devnull obteve a resposta correta neste comentário:

Você era bem próximo, basta dizer ao vim para ler em STDIN:

grep foo | vim -

Noumenon
fonte
0

Para expandir a resposta de Anthon para um caso em que há mais de uma correspondência, em alguns casos pode ser útil usar head -1( nesta resposta ) para selecionar apenas o primeiro resultado:vim "$(grep -l STRING FILES|head -1)"

EL_DON
fonte
0

Se você estiver executando um comando longo que tenha grep em algum lugar no meio dele, você também poderá executar

vim `command1 | grep whatever | awk '{do_something_else}'`
Greg
fonte