Estou procurando a melhor maneira de pesquisar e substituir (com confirmação) em todos os arquivos de projeto no Vim. Por "arquivos de projeto", quero dizer arquivos no diretório atual, alguns dos quais não precisam ser abertos.
Uma maneira de fazer isso pode ser simplesmente abrir todos os arquivos no diretório atual:
:args ./**
e, em seguida, faça a pesquisa e substitua em todos os arquivos abertos:
:argdo %s/Search/Replace/gce
No entanto, quando faço isso, o uso de memória do Vim salta de algumas dezenas de MB para mais de 2 GB, o que não funciona para mim.
Também tenho o plug- in EasyGrep instalado, mas quase nunca funciona - ou não encontra todas as ocorrências ou apenas trava até que eu pressione CtrlC. Até agora, minha forma preferida de realizar esta tarefa é ack-grep para o termo de pesquisa, usando sua janela de correção rápida, para abrir qualquer arquivo que contenha o termo e não tenha sido aberto antes, e finalmente :bufdo %s/Search/Replace/gce
.
Estou procurando um plug-in bom e funcional que possa ser usado para isso ou, alternativamente, um comando / sequência de comandos que seria mais fácil do que o que estou usando agora.
Respostas:
Greplace funciona bem para mim.
Há também uma versão pronta para patógenos no github.
fonte
:Gsearch
e:Gbuffersearch
existir, mas quando digito:Greplace
entendoNot an editor command: Greplace
.:Gsearch [<grep-option(s)>] [[<pattern>] [<filename(s)>]]
então você poderia fazer uma pesquisa recursiva usando, por exemplo::Gsearch -r pattern dir/
A outra grande opção aqui é simplesmente não usar o vim:
ou se você tem alguma forma de gerar uma lista de arquivos, talvez algo assim:
e assim por diante!
fonte
sed
regexes, que são essencialmente expressões regulares básicas POSIX.2, mas não exatamente (isso está na página de manual) - eles permitem a\n
correspondência de novas linhas e algumas outras coisas semelhantes. Eles são, portanto, praticamente iguais àsgrep
expressões regulares.find . -type f | LANG=C xargs sed -i '' 's/SEARCH/REPLACE/g'
EDIT: Use
cfdo
command em vez decdo
para reduzir significativamente a quantidade de comandos que serão executados para fazer isso (porquecdo
executa comandos em cada elemento enquantocfdo
executa comandos em cada arquivo)Graças ao
cdo
comando adicionado recentemente , agora você pode fazer isso em dois comandos simples, usando qualquergrep
ferramenta instalada. Não são necessários plug-ins extras !:(
cdo
executa o comando fornecido para cada termo na lista de correções rápidas, que o seugrep
comando preenche.)(Remova
c
no final do segundo comando se quiser substituir cada termo de pesquisa sem confirmar a cada vez)fonte
:cdo update
para salvar as alterações em todos os arquivos.c
no final do segundo comando (apenas useg
) para que ele procure e substitua sem pedir confirmaçãoupdate
, eu tinha que:cdo %s/<search term>/<replace term>/g | update
Decidi usar ack e Perl para resolver esse problema a fim de aproveitar as vantagens das expressões regulares Perl completas mais poderosas em vez do subconjunto GNU.
Explicação
ack
ack é uma ferramenta de linha de comando impressionante que é uma mistura de
grep
,find
e expressões regulares Perl completas (e não apenas o subconjunto GNU). É escrito em Perl puro, é rápido, tem destaque de sintaxe, funciona no Windows e é mais amigável para os programadores do que as ferramentas de linha de comando tradicionais. Instale-o no Ubuntu comsudo apt-get install ack-grep
.xargs
Xargs é uma antiga ferramenta de linha de comando Unix. Ele lê itens da entrada padrão e executa o comando especificado seguido pelos itens lidos para a entrada padrão. Então, basicamente, a lista de arquivos gerados por ack está sendo anexada ao final do
perl -pi -E 's/pattern/replacemnt/g'
comando.perl -pi
Perl é uma linguagem de programação. A opção -p faz com que Perl crie um loop em torno de seu programa que itera sobre argumentos de nome de arquivo. A opção -i faz com que o Perl edite o arquivo no local. Você pode modificar isso para criar backups. A opção -E faz com que Perl execute uma linha de código especificada como o programa. Em nosso caso, o programa é apenas uma substituição de regex Perl. Para obter mais informações sobre as opções de linha de comando Perl
perldoc perlrun
. Para obter mais informações sobre Perl, consulte http://www.perl.org/ .fonte
talvez faça isso:
Explicação:
:noautocmd vim /Search/ **/*
⇒ lookup (vim
é uma abreviatura devimgrep
) padrão em todos os arquivos em todos os subdiretórios do cwd sem acionar autocmds (:noautocmd
), para aumentar a velocidade.:set hidden
⇒ permite que buffers modificados não sejam exibidos em uma janela (pode estar em seu vimrc):cfirst
⇒ pular para o primeiro resultado da pesquisaqa
⇒ iniciar a gravação de uma macro no registrador a:%s//Replace/gce
⇒ substituir todas as ocorrências do último padrão de pesquisa (ainda/Search/
naquele momento) porReplace
:g
bandeira)c
bandeira)e
flag):cnf
⇒ pula para o próximo arquivo na lista criada pelovim
comandoq
⇒ macro para parar a gravação1000@a
⇒ reproduz macro armazenada no registrador 1000 vezes:wa
⇒ salvar todos os buffers modificados* EDITAR * Vim 8 vias:
A partir do Vim 8, há uma maneira melhor de fazer isso, pois
:cfdo
itera em todos os arquivos na lista de correções rápidas:fonte
vim
tenha me conquistado para muitas coisas, acho que vou ficar com o PowerGrep com isso.Preencher a
:args
partir de um comando shellÉ possível (em alguns sistemas operacionais 1 )) fornecer os arquivos por
:args
meio de um comando shell.Por exemplo, se você tiver o ACK 2 instalado,
irá pedir ao ack para retornar uma lista de arquivos contendo 'padrão' e colocá-los na lista de argumentos.
Ou com o grep simples, acho que seria:
Você pode então apenas usar
:argdo
conforme descrito pelo OP:Preencher a
:args
partir da lista de correção rápidaVerifique também a resposta de nelstrom a uma pergunta relacionada que descreve um comando simples definido pelo usuário que preenche o arglist da lista de correções rápidas atual. Isso funciona muito bem com muitos comandos e plug-ins cuja saída acaba na lista de correções rápidas (
:vimgrep
,:Ack
3 ,:Ggrep
4 ).A sequência para realizar uma pesquisa ampla do projeto poderia então ser feita com:
onde
:Qargs
é a chamada para o comando definido pelo usuário que preenche o arglist da lista de correções rápidas.Você também encontrará links na discussão a seguir para plug-ins simples que reduzem esse fluxo de trabalho a 2 ou 3 comandos.
Links
fonte
Mais uma opção em 2016, o plugin far.vim :
fonte
Se você não se importa em introduzir dependência externa, desenvolvi um plugin ctrlsf.vim (depende de ack ou ag ) para fazer o trabalho.
Ele pode formatar e exibir o resultado da pesquisa de ack / ag e sincronizar suas alterações no buffer de resultados com os arquivos reais no disco.
Talvez a demonstração a seguir explique mais
fonte
A etapa 1 preenche a lista de correção rápida com os itens que você deseja. Nesse caso, ele é propagado com os termos de pesquisa pelos quais deseja alterar
grep
.cfdo
executa o seguinte comando em cada arquivo na lista de correções rápidas. Digite:help cfdo
para obter detalhes.s/<search term>/<replace term>/g
substitui cada termo./g
significa substituir todas as ocorrências no arquivo.| update
salva o arquivo após cada substituição.Eu juntei tudo com base nesta resposta e seus comentários, mas senti que merecia sua própria resposta, pois está tudo em um só lugar.
fonte
2. :cfdo %s/<search term>/<replace term>/g | update
Sem o%
, apenas a primeira ocorrência do padrão é substituída.%s
funciona no vim regular também.Basicamente, eu queria substituir em um único comando e, mais importante, dentro do próprio vim
Com base na resposta de @Jefromi, criei um atalho de teclado, que defini no meu arquivo .vimrc como este
agora do vim, com um golpe de leader + r, pego o comando carregado no vim, que edito como a seguir,
Portanto, eu faço a substituição com um único comando e, mais importante, dentro do próprio vim
fonte