Como adicionar números de linha permanentes a um arquivo?

Tenho um arquivo de texto como este (usando gVim no Windows)

foo bar baz quux corge grault garply waldo fred plugh [...150 more lines...] xyzzy thud 

Quero adicionar um número a cada linha do arquivo. Não usando :set number, mas para adicionar o número como texto antes de cada linha, da seguinte maneira, para que o número faça parte do arquivo.

1. foo bar baz quux 2. corge grault garply 3. waldo fred plugh [...~150 more lines...] 155. xyzzy thud 

Comentários

  • awk é provavelmente a ferramenta para este trabalho. Mas eu ‘ m no Windows (suspiro).
  • Respondi aqui , deixa pra lá 🙂
  • Talvez .. Ou isso é mais geral?
  • É ‘ semelhante, mas eu não ‘ não sei o que são números de linha permanentes. Em segundo lugar, a outra pergunta é sobre todas as linhas (e a resposta faz isso) para gVim no Windows especificamente e esta é uma lista numerada simples para um parágrafo apenas no vim simples.
  • Bem, acho que essa postagem usa ” permanente ” não indica que o buffer deve ser modificado e que os números não estão ‘ t alguma coisa puramente visual (igual a você). O motivo para especificar gvim no Windows é evitar utilitários externos como cat ou nl, que podem numerar linhas, mas não são ‘ t geralmente disponível no Windows (como OP indica em seu comentário sobre awk). As duas principais soluções são Vim puro. Por último, todas as linhas versus um para é apenas uma questão de seleção de intervalo. Claramente, não é um grande problema.

Resposta

No estilo Vim puro:

:%s/^/\=line(".").". " 

Explicação:

:%s/^/ " the substitution will be applied to the beginning of every line \= " the rest of the replacement part is an expression line(".").". " " the expression returns the current line number concatenated with a dot and a space 

Veja :help \= e :help line().

Usar uma expressão na parte de substituição é muito poderoso e FWIW um bom ponto de entrada para vimscript.

Comentários

  • Como posso adicionar este comando muito útil a um mapa de teclado no vimrc?
  • Para chegar ao tópico de ajuda do vim para substituição: :help sub-replace-expression

Resposta

Uma coisa boa sobre macros Vim é que elas podem recursar (elas podem invocar a si mesmas ):

  1. Limpar registro q: qqq
  2. Adicione o número à primeira linha: ggI1. (não se esqueça do espaço!)
  3. Volte para o início da linha e comece a gravar uma macro: 0qq
  4. Copie o número:
  5. Mova uma linha para baixo e cole o número: +P
  6. Volte para o início da linha e incrementar o número: 0<c-a>
  7. Volte para o início da linha (para que a macro não se quebre quando chega a dois dígitos!): 0
  8. Chame a macro uma vez, para torná-la recursiva. Neste ponto, ainda não há nada no registro q, então nada acontecerá: @q.
  9. Salve a macro: q
  10. Chame a macro mais uma vez e observe as faíscas voarem !: @@

A macro irá em seguida, continue chamando a si mesmo até chegar ao final do arquivo.

Você pode usar o truque da macro recursiva para muitos outros problemas semelhantes, portanto, é bom estar ciente.

Se você não quiser usar uma macro recursiva por algum motivo, pode omitir as etapas 1 e 8 e usar uma contagem para executar a macro várias vezes, por exemplo 100@q executará a macro q 100 vezes.

Comentários

  • Coisas poderosas, eu me curvo ao seu domínio. As macros são como magia negra para mim …
  • @ropata, uma macro é apenas uma sequência de comandos do modo normal (principalmente).
  • @romainl Acho que ‘ É melhor pensar nisso como uma sequência de teclas .
  • @Rich, pode ser uma sequência de muitas coisas, incluindo ex comandos.
  • @romainl Sim, isso ‘ é por isso que acho ‘ melhor pensar nisso como combinações de teclas. Ele reproduz exatamente o que você digita no teclado (incluindo, como você diz, ex comandos), como se você tivesse digitado tudo manualmente.

Resposta

Gosto de usar o comando global vim para realizar tarefas como esta. Isso se aplica à adição de iteração ao início de uma linha ou à modificação de um símbolo no texto. Parece mais complicado do que as outras soluções, mas é um padrão bastante flexível para usar quando você o tiver em mãos e é fácil de modificar sem muito pensamento.

Primeiro, escolha seu intervalo (quais linhas você deseja aplicar isso). Eu costumo usar marcas (por exemploma na primeira linha e mb na segunda, mas você também pode usar números de linha ou seleção visual) e, em seguida, inserir uma modificação de o seguinte comando (atualmente ajustado para o seu caso de uso)

:let i=1|"a,"bg/^/s/^/\=i.". "/|let i=i+1 

Desconstrução

:let i=1 

Isso configura a variável i com um valor inicial. Normalmente as listas começam com 1, então estou definindo i como 1.

| 

A barra inicia um novo comando

"a,"b 

Isso define o intervalo do próximo comando. Estou indo da marca a para a marca b , que seria definido na primeira e última linha da sua lista.

g/^/ 

Este é o comando global. Ele procura no arquivo (ou intervalo) por uma dada expressão regular e irá executar o resto da linha de comando em cada uma das linhas correspondentes. Estou correspondendo a cada linha pesquisando por “início da linha”. Se você tivesse um texto como

Item some txt other text Item second item whatever Item third 

e só quisesse colocar esses rótulos antes de Item e ignorar as outras linhas, faça g/Item/ ou g/^Item/ (assumindo o texto literal do item )

s/^/\=i.". "/ 

Isso executa a expressão regular para substituir o início da linha com o valor de i concatenado com a .. Geralmente você pode fazer isso com qualquer coisa (substitua o rótulo Item pelo número, por exemplo).

|let i=i+1 

Mesmo que a barra inicie um novo comando, ela configura um segundo comando para ser executado dentro do comando global, em vez de depois que o global for concluído. O resultado é que incrementamos i antes que a próxima linha seja processada por g. Aqui está outro lugar de flexibilidade. A modificação de i pode ser qualquer coisa (incre por 2, chame uma função que gere o próximo elemento da sequência de Fibonacci, qualquer que seja).

Resposta

Adicione números a todas as linhas

É possível usar :%!nl -ba ou :%!cat -n comandos que adicionarão números de linha a todas as linhas.

No Windows, você “é necessário ter Cygwin / MSYS / SUA instalado.

Adicionar números às linhas selecionadas

Para adicionar números apenas às linhas selecionadas, selecione-os em modo visual ( v e cursores) e, quando terminar – execute o comando: :%!nl (ignore as linhas em branco) ou :%!cat -n (linhas em branco incluídas).

Formatação

Para remover espaços extras, selecione-os no bloco visual ( Ctrl + v ) e removê-los ( x ).

Para adicionar alguns caracteres (., :, ) após os números, selecione-os no bloco visual ( Ctrl + v ) e anexe o caractere ( A , digite o caractere e termine com Esc ).

Comentários

  • Isso não fornece a mesma formatação fornecida na questão. No entanto, gosto da simplicidade da solução.
  • @KarlYngveLerv å g Obrigado, incluiu isso na resposta.

Resposta

Uma modificação da resposta do romainl :

:%s/^\(\d\+\. \)\?/\=line(".").". " 

Isso não apenas adicionará os números das linhas, mas também substituirá os números das linhas existentes se eles já estiverem lá. Ou, se você inseriu uma linha no meio, ele renumerará tudo conforme o esperado.

Isso funciona substituindo qualquer número seguido por um. E um espaço no início da linha por um novo número . Isso obviamente será interrompido se você tiver uma linha que já começa com este padrão, então use com reflexão.

A parte adicionada:

  • ^ – Início da linha
  • \( – Iniciar novo subgrupo
  • \d\+ – Corresponde a um dígito uma ou mais
  • \. – Corresponde a um ponto (.) e um espaço .
  • \) – Fim do subgrupo
  • \? – Torne o grupo opcional, para que funcione como antes se ainda não houvesse nenhum número nesta linha.

Dica bônus :
Para remover os números de linha, você pode usar o mesmo padrão com a parte de repalce vazia:

:%s/^\(\d\+\. \)\?// 

Resposta

I1. <esc>^qqyWjP^<C-a>q 

Isso numera as duas primeiras linhas e você pode pressionar @q para numerar as linhas subsequentes (ou digite ex. 18@q se desejar numerar um total de 20 linhas).

Explicação:

I1. <esc> Number the first line hqq Go back to the start of the line and start recording a macro yWjP Copy the line number to the next line ^<C-a> Increment the next line"s line number q Finish recording 

A vantagem disso é que não requer nenhum comando externo, o que é útil se você estiver trabalhar com Vim no Windows, por exemplo.

Comentários

  • Depois de digitar 1. <esc>h você está no segunda coluna, não primeira coluna. Eu substituiria h por 0, após o que acho que sua solução deve ser muito boa.
  • @KarlYngveLerv å g Ops, foi um erro de digitação. Obrigado, consertou.
  • Sem problemas. No entanto, você ainda não atualizou a explicação. Além disso: em muitos teclados, ^ aguarda um segundo caractere para permitir combinações de digitação como ^a -> â. Ainda concordo que é a melhor solução, mas acho que isso também deve ser mencionado.

Resposta

I acho que a resposta escolhida é a melhor, mas no espírito da variedade, vou oferecer uma alternativa usando um programa externo:

:%!cat -n 

Isso filtrará todo o seu buffer (conforme indicado por %) por meio do programa externo, cat, onde o -n sinalizador precede cada linha de entrada com um número de linha.

Isso, é claro, requer que você tenha cat instalado, o que é verdadeiro para (provavelmente) todos os Unix como sistemas.

Verifique :help :range! para obter mais detalhes sobre a filtragem de programas externos.

Comentários

  • Sei que quem fez a pergunta está usando o gVim no Windows, então essa solução provavelmente não ‘ funcionará lá. No entanto, acho que ainda oferece algumas oportunidades para outras t o aprenda com ele.
  • Se você ‘ instalou msysgit e adicionou isso ao seu PATH (IIRC it ‘ s uma opção de instalação), esta solução também deve funcionar no Windows.
  • cat -n não é POSIX, mas nl é, então pode ser um melhor opção.

Resposta

Uma solução um pouco hackeada pode ser a seguinte (tudo escrito entre < e> devem ser inseridos após pressionar Ctrl + v ):

:%normal :redir @"<Enter>:-=<Enter>:redir END<Enter>I<C-R>".<Tab><Esc>kdd 

Desconstrução

:%normal {commands} 

executa o comando de modo normal em cada linha especificada pelo intervalo, neste caso cada linha

:redir @" 

redireciona todas as saídas feitas pelos comandos ex para o buffer sem nome.

:.= 

é um comando ex que gera a linha atual número (com uma nova linha precedente, infelizmente)

:redir END 

para de redirecionar para o buffer sem nome

I<C-R>".<Tab><Esc> 

insere o conteúdo do buffer sem nome com a. e uma tabulação para a frente de cada linha e sai do modo de inserção.

kdd 

sobe uma linha e remove a nova linha que é o resultado de:. = comando.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *