AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 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 没有移动到预期的行

  • 772

我的最终目标是在句子分隔符上拆分文本。然而,它不应该被分成句子,而是在块中。1000 行,加上当前句子的其余部分。但在下面的实验中,为了简单起见,我只使用了 2 行。

考虑 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.

执行后:

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

结果符合预期。缓冲区包含:

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

但是在下一次运行之后

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

缓冲区包含:

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

这里发生了什么?为什么它不移动到第二行line 3. line 3. line 3.?

但我希望以下文本保留在缓冲区中

line 3. line 3.
line 4. line 4. line 4.
line 5. line 5. line 5.
vim
  • 2 2 个回答
  • 139 Views

2 个回答

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

    问题的根源在于gv最后。这是不必要的,因为视觉选择从命令的前一部分持续存在。更糟糕的是,这并不是无害的,因为当您gv已经处于可视模式时,当前和以前的可视区域会交换。意味着之前的选择被重新选择了!

    即使先前的选择被删除,选择也会应用于同一区域……或者至少是它的剩余部分。在这种情况下,这将是剩余line 2.句子中的第一个。

    为了演示,请注意输入两次时会发生什么:2G)hvgggvd. 这正是命令行上发生的事情,减去写入磁盘,但使用 100% 正常模式命令。

    所以无论如何我们只需要失去gv并且这将起作用:

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

    除此之外,此命令中还有很多可以清理的噪音。exec不需要两个s 和随附的引号:

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

    更新:针对您的其中一个评论...

    '<,'>
    

    是一种逐行操作,从最后选择的可视区域的第一行到同一区域的最后一行进行选择。要获得字符明智的范围,您需要像这样使用 back-tics:

    `<,`>
    

    但是,这不适用于:w......它只是一个逐行操作。

    我要指出的是,这超出了您的问题的范围,该问题询问为什么要删除特定的文本......所以您可能想针对按字符写入文件提出一个单独的问题。

    更新 2:这是解决您的问题的完全不同的方法......

    使用以下命令创建宏

    :let @q = ")hs\<CR>\<ESC>k:let @a=@a+1\<CR>:1,.w /tmp/part\<C-R>a.txt\<CR>dgg"
    
    • 运行这个命令::let @a = 0.
    • 将光标放在一个句子上,然后在普通模式下运行宏@q

    这将按照您描述的方式运行:句子及其上方的所有内容都将写入一个名为的文件/tmp/part1.txt,并且保存的文本将被删除。现在移动到任何其他句子并@q再次执行,这一次会发生同样的事情,但它会写入/tmp/part2.txt. 每次运行宏时,文件名都会自动递增。您可以使用 再次重置索引:let @a = 0。

    与之前的更新一样,这并没有解决所提出的实际问题,但因为我很好,我提供了一些额外的帮助。(而且 OP 仍然不会接受我的回答。)

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

    我终于找到了公认的解决方案。感谢@B 层的合作(例如,提到该w命令仅将整行写入文件)。我赞成你的回答。

    :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
    

    之后,如果最后一个块短于 1000 行,则按重复命令,@:您将收到错误消息。只需手动保存其余部分。

    经过 5 次处决后,我得到了预期:

    $ 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
    

    对于那些想要使用它的人,我将简要解释关键步骤:

    :1000

    移动到第 1000 行(块至少应为 1000 行)

    exec 'normal! )hvggd'
    

    移动到下一个句子的开头并返回一个字符,这样下一个句子的第一个字符就不会被删除。要正确处理分布在多行的句子,whichwrap=h,l应该设置,据我所知,这不是默认设置。选择从当前光标位置到开头的所有内容并将其删除。删除的内容将保存在寄存器中。

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

    将寄存器内容(块)写入文件

    我假设不会超过 99 个块。如果需要更多,请根据需要调整与填充相关的部分。

    • -1

相关问题

  • Centos7 - 最小安装:echo $TERM 给我 'linux' 和 'tput colors' 给我 '8'。如何改变它?

  • 如何在不安装 nano 的情况下摆脱“nano not found”警告?

  • 在 Vim 中删除到命令行末尾

  • 如何在 vim 中使用 :e 忽略目录?

  • 将默认编辑器更改为 vim for _ sudo systemctl edit [unit-file] _

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

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

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve