Vim/Buscas e substituições

Origem: Wikilivros, livros abertos por um mundo aberto.

< Vim

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

Posiciona 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
$ ............. significa para o vim final do arquivo
% ............. representa o arquivo atual

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"

Uma dica é colocar no seu arquivo de configuração 'vimrc' veja como editar preferências

set ignorecase ............... ignora maiúsculas e minúsculas na bucsca
set smartcase ................ se sua busca contiver maiúsculas ele passa a considera-las
set hlsearch ................. mostra o que está sendo buscado em cores
set incsearch ................ ativa a busca incremental

se você não sabe ainda como colocar estas preferências no arquivo de configuração pode ativa-las em modo de comando precedendo-as com dois pontos, assim:

:set ignorecase<enter>
  • 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\}$
^ .............. representa começo de linha
  • 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('.'). ' '
  • Modificando todas as tags html para minusculo
:%s/<\([^>]*\)>/<\L\1>/g
  • move linhas 10 a 12 para além da linha 30
:10,12m30

[editar] O comando global 'g'

  • 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 $

Obs: O comando copy pode ser abreviado 'co' ou ainda você pode usar 't' para mais detalhes leia

   :h co

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

pegar caracteres numericos e jogar no final do arquivo?

 :g/^\d\+.*/m $

inverter a ordem das linhas do arquivo?

 :g/^/m0

apagar as linhas que contém "Line commented"

 :g/Line commented/d

copiar determinado pardrão para um registro

 :g/pattern/ normal "Ayy

copiar linhas que contém um padrão e a linha subsequênte para o final

 :g/padrão/;+1 copy $

[editar] Dicas

Para colocar a última busca em uma substituição faça:

 :%s/Control-r//novo/g

A dupla barra corresponde ao ultimo padrão procurado, e portanto o comando abaixo fará a substituição da ultima busca por casinha

 :%s//casinha/g

[editar] Filtrando arquivos com o vimgrep

Por vezes sabemos que aquela anotação foi feita, mas no momeno esquecemos em qual arquivo está, no exemplo abaixo procuramos a palavra dicas à partir da nossa pasta pessoal pela palavra 'dicas' em todos os arquivos com extensão 'txt'

~/ ............ equivale a /home/user
:lvimgrep /dicas/ ~/**/*.txt | ls

O comando

[editar] Copiar a partir de um ponto

 :19;+3 co $

O vim sempre necessita de um intervalo (inicial e final) mas se você usar ';' ele considera a primeira linha como segundo ponto do intervalo, e no caso acima estamos dizendo (nas entrelinhas) linhas 19+3

De forma hanáloga podemos usar como referência um padrão qualquer

:/palavra/;+10 m 0

O comando acima diz: à partir da linha que contém 'palavra' incluindo as 10 próximas linhas mova 'm' para a primeira linha '0', ou seja antes da linha 1.

[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 não tem awk, e logo a melhor solução mesmo é usar o vim:

:let i=1 | 10,20 g/texto\d\+texto/s/\d\+/\=submatch(0)+i/ | let i=i+1

Observação: 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

[editar] Dicas do dicas-l

[editar] Junção de linhas com vim

Colaboração: Rubens Queiroz de Almeida

Recentemente precisei combinar, em um arquivo, duas linhas consecutivas. O arquivo original continha linhas como

 Matrícula: 123456
 Senha: yatVind7kned
 Matrícula: 123456
 Senha: invanBabnit3

E assim por diante. Eu precisava converter este arquivo para algo como:

 Matrícula: 123456 - Senha: yatVind7kned
 Matrícula: 123456 - Senha: invanBabnit3

Para isto, basta emitir o comando:

 :g/^Matrícula/s/\n/ - /

Explicando:

g/^Matrícula 	busca, no arquivo inteiro (g) pela palavra Matrícula na primeira coluna
s/\n/ - / 	substitui a quebra de linha (\n), pelos caracteres ** - **. 
"Esta substituição faz a junção das duas linhas adjacentes

Voltar ao índice