AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 424798
Accepted
ka3ak
ka3ak
Asked: 2018-02-18 05:16:15 +0800 CST2018-02-18 05:16:15 +0800 CST 2018-02-18 05:16:15 +0800 CST

vim não se move para a linha esperada

  • 772

Meu objetivo final é dividir um texto em delimitadores de frase. No entanto, não deve ser dividido em frases, mas em pedaços ca. 1000 linhas e mais o restante da frase atual. Mas no experimento abaixo eu uso apenas 2 linhas para simplificar.

Considere o seguinte texto em um buffer VIM:

line 1. line 1. line 1.
line 2. line 2. line 2.
line 3. line 3. line 3.
line 4. line 4. line 4.
line 5. line 5. line 5.

Após a execução de:

:2 | exec 'normal! )hvgg' | exec "'<,'>w /tmp/part1.txt" | exec 'normal! gvd'

O resultado é o esperado. Buffer contém:

line 2. line 2.
line 3. line 3. line 3.
line 4. line 4. line 4.
line 5. line 5. line 5.

Mas depois da próxima corrida

:2 | exec 'normal! )hvgg' | exec "'<,'>w /tmp/part2.txt" | exec 'normal! gvd'

buffer contém:

line 2.
line 3. line 3. line 3.
line 4. line 4. line 4.
line 5. line 5. line 5.

O que está acontecendo aqui? Por que não se move para a segunda linha que é line 3. line 3. line 3.?

Mas eu esperaria que o seguinte texto permanecesse no buffer

line 3. line 3.
line 4. line 4. line 4.
line 5. line 5. line 5.
vim
  • 2 2 respostas
  • 139 Views

2 respostas

  • Voted
  1. B Layer
    2018-02-18T07:23:55+08:002018-02-18T07:23:55+08:00

    A raiz do problema está gvno final. É desnecessário, pois a seleção visual persiste da parte anterior do comando. Pior, não é inofensivo porque quando você faz gvquando já está no modo Visual, a área Visual atual e anterior são trocadas . Significa que a seleção anterior foi selecionada novamente!

    Mesmo que a seleção anterior tenha sido excluída, a seleção é aplicada à mesma área... ou pelo menos o que resta dela. Nesse caso, essa seria a primeira das line 2.frases restantes.

    Para demonstrar, observe o que acontece quando você entra nisso duas vezes: 2G)hvgggvd. Isso é exatamente o que está acontecendo na linha de comando, menos a gravação no disco, mas com comandos de modo 100% Normal.

    De qualquer forma, só precisamos perder o gve isso funcionará:

    :2 | exec 'normal! )hvgg' | exec "'<,'>w! /tmp/part1.txt" | exec 'normal! d'
    

    Além disso, há muito ruído neste comando que pode ser limpo. Dois dos execs e as aspas que os acompanham não são necessários:

    :2 | exec 'norm! )hvgg' | '<,'>w! /tmp/part1.txt | norm! d
    

    Atualização: Em resposta a um de seus comentários, este...

    '<,'>
    

    é uma operação linear que seleciona da primeira linha da última área visual selecionada até a última linha da mesma área. Para obter intervalos sábios de caracteres, você precisa usar back-tics como este:

    `<,`>
    

    No entanto, isso não funcionará com :w... é apenas uma operação linear.

    Gostaria de salientar que isso está fora do escopo da sua pergunta, que pergunta por que um determinado texto está sendo excluído .... portanto, você pode fazer uma pergunta separada para gravação em arquivo.

    Atualização 2: Aqui está uma abordagem totalmente diferente para o seu problema...

    Crie uma macro com o seguinte comando

    :let @q = ")hs\<CR>\<ESC>k:let @a=@a+1\<CR>:1,.w /tmp/part\<C-R>a.txt\<CR>dgg"
    
    • Execute este comando: :let @a = 0.
    • Coloque o cursor em uma frase e, no modo Normal, execute a macro com@q

    Isso se comportará da maneira que você descreve: a frase e tudo acima dela serão gravados em um arquivo chamado /tmp/part1.txte o texto salvo será excluído. Agora vá para qualquer outra frase e faça @qnovamente e desta vez a mesma coisa acontecerá, mas ela será gravada em /tmp/part2.txt. Cada vez que você executar a macro, o nome do arquivo será incrementado automaticamente. Você pode redefinir o índice novamente com :let @a = 0.

    Como a atualização anterior, isso não está abordando a pergunta real, mas como sou legal, estou fornecendo uma ajuda extra. (E o OP ainda não aceita minha resposta.)

    • 4
  2. Best Answer
    ka3ak
    2018-02-18T23:21:02+08:002018-02-18T23:21:02+08:00

    Finalmente cheguei à solução aceita. Obrigado a @B Layer pela cooperação (por exemplo, mencionar que o wcomando apenas grava linhas completas em um arquivo). Eu votei a favor da sua resposta.

    :let i=1
    :1000 | exec 'normal! )hvggd' | exec 'if i<10 | let num="0" . i | else | let num=i | endif' | call writefile(split(@@, "\n", 1), '/tmp/test' . num . '.txt') | let i=i+1
    

    Depois disso, repita o comando pressionando @:se o último pedaço for menor que 1000 linhas, você receberá um erro. Basta salvar o restante manualmente.

    Após 5 execuções tive como esperado:

    $ wc -l /tmp/test*.txt
      1001 /tmp/test01.txt
      1000 /tmp/test02.txt
      1001 /tmp/test03.txt
      1006 /tmp/test04.txt
      1001 /tmp/test05.txt
    

    Para quem quiser usá-lo, explicarei resumidamente os principais passos:

    :1000

    Mover para a linha 1000 (os pedaços devem ter pelo menos 1000 linhas)

    exec 'normal! )hvggd'
    

    Mova para o início da próxima frase e um caractere para trás para que o primeiro caractere da próxima frase não seja excluído posteriormente. Para funcionar corretamente em frases que estão espalhadas por várias linhas, whichwrap=h,ldeve ser definido, o que não é o padrão até onde eu sei. Selecione tudo, desde a posição atual do cursor até o início e exclua-o. O conteúdo deletado será salvo no cadastro.

    call writefile(split(@@, "\n", 1), '/tmp/test' . num . '.txt')
    

    Escreva o conteúdo do registrador (o pedaço) em um arquivo

    Parti do pressuposto de que não haverá mais de 99 blocos. Se precisar de mais, ajuste a parte relacionada ao preenchimento conforme necessário.

    • -1

relate perguntas

  • Centos7 - instalação mínima: echo $TERM me dá 'linux' e 'tput colors' dá '8'. Como mudar isso?

  • Como se livrar dos avisos "nano não encontrado" sem instalar o nano?

  • Excluir até o final da linha de comando no Vim

  • Como ignorar diretórios usando: e no vim?

  • Altere o editor padrão para vim para _ sudo systemctl edit [unit-file] _

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve