Vim/Buscas e substituições
Buscas
editarPara 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.)
Substituições
editarPara 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.
Exemplos
editar- 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\>
Um exemplo prático da expressão regular que elimine todas as linhas nas quais houver uma palavra
que se repita pelo menos uma vez, ou seja, mantenha apenas palavras que só aparecem uma vez.
Digamos que tenhamos o seguinte arquivo
1Apple 1Apple 2Peach 2Peach 2Peach 3Beer 4Banana 4Banana 4Banana
A Solução seria
:%s/\v(.*)(\n\1)+//
Casando tudo .* seguido por uma quebra de linha \n, seguido pelo padrão precedente \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
O comando global 'g'
editar- 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 $
Reordenando parágrafos
editarDigamos que você tenha um arquivo com o seguinte conteúdo
\begin{rSubsection}{Example 1}{}{Redacted}{} \item Stuff I did \item Also did other things \end{rSubsection} \begin{rSubsection}{Example 2}{}{Redacted}{} \item Stuff I did \item Also did other things \end{rSubsection} \begin{rSubsection}{Example 3}{}{Redacted}{} \item Stuff I did \item Also did other things \end{rSubsection} \begin{rSubsection}{Example 4}{}{Redacted}{} \item Stuff I did \item Also did other things \end{rSubsection}
Para reordenar esses blocos de modo que o 4º bloco fique no começo e o bloco 1 fique no final
fazemos o seguinte:
Adicionamos uma linha ao final do arquivo
:$put _
Em seguida executamos o seguinte comando global
:g/Example [2-4]/normal! dapggP
Na prática o vim moverá os blocos 2 a 4 para o começo usando o comando "normal" dap (delete parágrafo)
gg que salta para o começo do arquivo e o comando de colar P.
Dicas
editarPara 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
Filtrando arquivos com o vimgrep
editarPor 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
Copiar a partir de um ponto
editar: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.
Dicas das lista vi-br
editarFonte: 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
Dicas do dicas-l
editarJunção de linhas com vim
editarColaboraçã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