Autocomplete da saída do grep

2

Como posso usar mais facilmente um nome de arquivo encontrado por grep como um argumento para vim :

$ grep -r foo *
lib/beatles/john.c
lib/pantera/phil.c
lib/pinkfloyd/roger.c
lib/pinkfloyd/richard.c
lib/whitestripes/elephant/jack.c

$ vim lib/pinkfloyd/roger.c

Para preencher automaticamente com o Bash, eu preciso digitar " l \t p \t i \t r \t o \t " porque muitos outros arquivos correspondem. Existe uma maneira mais fácil de dizer "Dê-me o terceiro arquivo encontrado?" Talvez algo como um destes:

$ vim $3        // Third line
$ vim 'roger'   // Only line with string 'roger'
$ vim TabTabTab // Each Tab completes a different filename from grep

Eu uso o Tmux e sei que posso subir e selecionar o nome do arquivo e depois colá-lo. Mas isso ainda é um pouco desajeitado, mesmo como usuário do VIM. Deve haver uma maneira melhor!

Observe que não estou procurando uma solução para criar o script da saída do grep , em vez disso, isso é algo que eu usarei manualmente, como grep e abrir arquivos com o VIM.

EDIT: Estou procurando uma solução geral, não uma que sempre segmente 'roger' ou sempre segmente o terceiro item.

    
por dotancohen 18.01.2016 / 10:09

2 respostas

2

Eu fiz um script para aplicar recursivamente a um padrão, e então eu posso selecionar uma das correspondências para que o vim abra o arquivo naquela linha. Chamo de vgrep (vim grep, embora também use awk ). O seguinte é o seu código:

#!/bin/bash
my_grep() {
        grep -Rn -I --color=auto --exclude-dir={.svn,.git} --exclude={tags,cscope.out} "$@" . 2>/dev/null
}
my_grep_color() {
        grep -Rn -I --color=always --exclude-dir={.svn,.git} --exclude={tags,cscope.out} "$@" . 2>/dev/null
}

awk '{
    print NR, $0
}' <(my_grep_color "$@")

awk '{
    lines[NR]=$1;
}

END{
    printf "Enter index: "
    getline num < "-";
    split(lines[num], s, ":")
    system("vim "s[1]" +"s[2])
}' <(my_grep "$@")

Estou chamando grep duas vezes apenas para destacar minhas correspondências. Você pode alterá-lo para que seja chamado apenas uma vez, mas perderá o destaque.

Uso:

Suponha que você queira abrir o vim na linha onde há uma palavra "Foo", você pode usá-lo assim: vgrep Foo

Se houver um arquivo foobar como:

a b c
Bar
e f Foo g
h i

vgrep produzirá isso:

1 ./foobar:3 e f Foo g
Enter index: 

Assim, você pode digitar 1 + enter e ele abrirá esse arquivo na terceira linha. Ele produzirá uma linha indexada para cada correspondência que encontrar.

Tenho certeza de que esse script pode ser melhorado, mas, para meus usos, ele funciona muito bem.

Além disso, considere o uso de ctags e cscope se você está trabalhando com C/C++ .

    
por 18.01.2016 / 12:03
0

Verifique se isso é útil:

Arquivo = 'grep -r foo / caminho / of / search / * | grep 'roger' '

WhichItem = 3

ThirdFile = 'grep -r foo / caminho / of / search / * | cabeça - $ WhichItem | cauda -1 '

    
por 18.01.2016 / 10:30