Vim/Buscas e substituições
Origem: Wikilivros, livros abertos por um mundo aberto.
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