Vim: Buscas e substituições
De Wikibooks
Tabela de conteúdo |
[editar] Buscas
Para fazer uma busca, certifique-se de que está em modo normal, pressione "/" e digite a expressão a ser procurada.
Para encontrar a primeira ocorrência de "foo" no texto:
/foo
busca a palavra 'foo'
//
repete a última busca
/teste/+3
posisiona o cursor três linhas após a ocorrência da palavra 'teste'
- Para encontrar as próximas ocorrências, tecle "n".
- Para encontrar as ocorrências anteriores, tecle "N".
Fazer buscas pelo valor hexadecimal de um caractere
/\%x69 ............... localiza a letra 'i' que em hexadecimal tem valor 069
Dica: Um meio mais rápido para encontrar a próxima ocorrência de uma palavra sob o cursor, é teclar "*". Para encontrar uma ocorrência anterior da palavra sob o cursor, tecle "#". (Para isso, o cursor deve estar posicionado sobre a palavra que deseja procurar.)
[editar] Substituições
Para fazer uma busca, certifique-se de que está em modo normal, em seguida digite use o comando ":s", conforme será explicado.
Para substituir "foo" por "bar" na linha atual:
:s/foo/bar
Para substituir "foo" por "bar" da primeira à décima linha do arquivo:
:1,10 s/foo/bar
Para substituir "foo" por "bar" da primeira à última linha do arquivo:
:1,% s/foo/bar
Ou simplesmente:
:% s/foo/bar
O comando ":s" possui muitas opções que modificam seu comportamento.
[editar] Exemplos
- Busca usando alternativas:
/end\(if\|while\|for\)
buscará "endif", "endwhile" e "endfor". Observe que é necessário "escapar" os caracteres \(, \| e \), caso contrário eles serão interpretados como caracteres comuns.
- Quebra de linha
/quebra\nde linha
- Ignorando maiúsculas e minúsculas
/\cpalavra usando \c o vim encontrará "palavra", "Palavra" ou até mesmo "PALAVRA"
- Procurando palavras repetidas
/\<\(\w*\) \1\>
- Multilinha
/Hello\_s\+World
buscará "Hello World", separados por qualquer número de espaços, incluindo quebras de linha. Buscará as três seqüências:
Hello World Hello World Hello World
- Buscar linhas de até 30 caracteres de comprimento
/^.\{,30\}$
- Apaga todas as tags html/xml de um arquivo
:%s/<[^>]*>//g
- Apaga linhas vazias
:%g/^$/d
ou
:%s/^[\ \t]*\n//g
- Remover duas ou mais linhas vazias entre parágrafos diminuindo para uma só linha vazia.
:%s/\(^\n\{2,}\)/\r/g
Você pode criar um mapeamento e colocar no seu ~/.vimrc
map ,s <esc>:%s/\(^\n\{2,}\)/\r/g<cr>
No exemplo acima ',s' é um mapeamento para reduzir linhas em branco sucessivas para uma só
- Remove não dígitos (não pega números)
:%s/^\D.*//g
- Remove final de linha DOS/Windows ^M que tem código hexadecimal igual a '0d'
:%s/\%x0d//g
- Troca palavras de lugar usando expressões regulares
:%s/\(.\+\)\s\(.\+\)/\2 \1/ - troca palavras de lugar
- Inserir numeração de linhas do arquivo
:%s/^/\=line('.'). ' '
- buscando um padrao e gravandoo em outro arquivo
:'a,'b g/^Error/ . w >> errors.txt
Para copiar linhas começadas com "Error" para o final do arquivo faça:
:g/^Error/ copy $
Entre as linhas que contiverem fred e joe substitua
:g/fred/,/joe/s/isto/aquilo/gic
As opções 'gic' correspondem a global, ignore case e confirm, podendo ser omitidas deixando só o global
[editar] Dicas
Para colocar a última busca em uma substituição faça:
:%s/Control-r//novo/g
a dupla barra corresponde ao ultimo padrao procurado, e portanto o comando abaixo fara a substituiçao da ultima busca por cazinha
:%s//cazinha/g
[editar] Dicas das lista vi-br
fonte: http://groups.yahoo.com/group/vi-br/message/853 Problema: Essa deve ser uma pergunta comum. Suponha o seguinte conteúdo de arquivo: ... // várias linhas texto1000texto // linha i texto1000texto // linha i+1 texto1000texto // linha i+2 texto1000texto // linha i+3 texto1000texto // linha i+4 ... // várias linhas
Gostaria de um comando que mudasse para
... // várias linhas
texto1001texto // linha i
texto1002texto // linha i+1
texto1003texto // linha i+2
texto1004texto // linha i+3
texto1005texto // linha i+4
... // várias linhas
ou seja, somasse 1 a cada um dos números entre os textos especificando como range as linhas i,i+4
:10,20! awk 'BEGIN{i=1}{if (match($0, "[0-9]+")) print "texto"
(substr($0, RSTART, RLENGTH) + i++) "texto"}'
Mas muitos sistemas nao tem awk, e logo a melhor solucao mesmo eh usar o vim:
:let i=1 | 10,20 g/texto\d\+texto/s/\d\+/\=submatch(0)+i/ | let i=i+1
Obs: 10,20 é o intervalo, ou seja, da linha 10 até a linha 20
Para maiores informações sobre buscas e substituições:
:help / :help :s :help pattern

