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

voltar ao índice

Ferramentas pessoais