Vim:在多行之间插入相同字符

有时我想跨多行编辑某个可视文本块。

例如,我会取一个看起来像这样的文本:

name
comment
phone
email

让它看起来像这样

vendor_name
vendor_comment
vendor_phone
vendor_email

现在我要做的是…

  1. 通过按V,然后按j四次,选择一个块的所有4行。
  2. >缩进。
  3. 返回一个带有h的字母。
  4. 使用Ctrlv切换到阻塞可视模式。
  5. 通过按j四次向下选择四行。此时,您已经选择了一个4x1可视空白块(四行一列)。
  6. C。注意这里向左缩进了一列。
  7. 输入不带引号的" vendor_"。注意我们要放回的额外空间。
  8. Esc。这是我使用Esc退出插入模式的少数几次之一。Ctrlc只编辑第一行。
  9. 重复步骤1。
  10. & lt;缩进。

如果单词前至少有一列空白,我就不需要缩进。如果我不需要用c清除可视块,我就不需要空格。

但是如果我必须清除,那么是否有一种方法来做我上面所做的而不创建所需的缩进空白?

另外,为什么一次编辑多行只能通过退出插入模式Esc而不是Ctrlc来工作?


这里有一个更复杂的例子:

name    = models.CharField( max_length = 135 )
comment = models.TextField( blank = True )
phone   = models.CharField( max_length = 135, blank = True )
email   = models.EmailField( blank = True )

name    = models.whatever.CharField( max_length = 135 )
comment = models.whatever.TextField( blank = True )
phone   = models.whatever.CharField( max_length = 135, blank = True )
email   = models.whatever.EmailField( blank = True )

在这个例子中,我将在.上执行垂直可视块,然后在插入模式下重新插入它,即键入.whatever.。希望现在你能看到这种方法的缺点。我被限制只能选择一列的文本在竖直方向上都是一样的

242469 次浏览
  1. 将光标移动到name中的n
  2. 进入可视块模式(Ctrlv)。
  3. j三次(或3 j)向下跳转3行;G(大写g)跳转到最后一行
  4. I(大写i)。
  5. 输入vendor_。注意:它只会在< >强第一个< / >强行更新屏幕——直到Esc被按下(6.),此时所有行都将被更新。
  6. Esc

mini-screencast示范方法

必须使用大写的I而不是小写的i,因为小写的i被解释为文本对象的开始,这本身非常有用,例如用于在标记块(it)内进行选择:

迷你屏幕播放显示'it'文本对象的有用性

我将使用宏来记录我的操作,然后重复它。

  1. 将光标放在的名字中的第一个字母上。
  2. 点击qq开始记录到q缓冲区。
  3. 点击进入插入模式,输入vector_,然后点击Esc离开插入模式。
  4. 现在按0返回行首。
  5. 现在按j向下。
  6. 现在再次点击停止录制。

现在你有了一个漂亮的宏。

输入3 @q来执行宏三次以完成其余的行。

假设你有这个文件:

something


name
comment
phone
email


something else
and more ...

你想在"name", "comment", "phone"和"email"前面添加"vendor_", 不管它们出现在文件的哪个位置

:%s/\<\(name\|comment\|phone\|email\)\>/vendor_\1/gc

c标志将提示您确认。如果你不想要这个提示,你可以去掉它。

另一种方法是将 (dot)命令与结合使用。

  1. 将光标移动到想要开始的位置
  2. 新闻
  3. 输入你想要的前缀(例如vendor_)
  4. esc
  5. j向下一行
  6. 输入以重复最后的编辑,自动再次插入前缀
  7. j之间快速交替

我发现对于少量的添加,这种技术通常比可视块模式更快,并且有额外的好处,如果你不需要在范围内的每一行插入文本,你可以通过按额外的j轻松跳过它们。

注意,对于大量的连续添加,块方法或宏可能会更好。

:%s/^/vendor_/

还是我遗漏了什么?

您还可能有这样的用例,您希望删除文本块并替换它。

像这样

Hello World


Hello World

Hello Cool


Hello Cool

你可以在两行中选择“World”。

为change键入c -现在您将处于插入模式。

插入你想要的东西,然后点击退出。

两者都垂直反射。它的工作原理就像'I',除了它用新文本替换块而不是插入它。

2016年1月更新

虽然公认的答案是一个很好的解决方案,这实际上是更少的按键,和更好的伸缩性-基于原则上公认的答案。

  1. 将光标移动到name中的n
  2. 进入可视块模式(ctrlv)。
  3. 新闻3 j
  4. I
  5. 输入vendor_
  6. esc

视觉插图 .

注意,这比提供的可接受答案的击键次数要少(比较步骤3)。我们只是计算要执行的j个操作的数量。

如果你启用了行号(如上所示),并且知道你希望移动到的行号,那么步骤3可以更改为#G,其中#是想要的行号。

在上面的例子中,这将是4 g。然而,当只处理几行号时,显式计数工作得很好。

  1. 使用CtrlV选择要修改的行
  2. < p >新闻:

    • :插入到所选内容之前。
    • 一个:在所选内容之后追加。
    • c:替换所选内容。
    • 李< / ul > < / >
    • 输入新的文本

    • Esc将更改应用到所有选定的行。
Use Ctrl+V to enter visual block mode
Move Up/Down to select the columns of text in the lines you want to comment.
Then hit Shift+i and type the text you want to insert.
Then hit Esc, wait 1 second and the inserted text will appear on every line
我想在只有vi(没有nano)的服务器上的一些配置文件中注释掉很多行,所以可视化方法也很麻烦 下面是我怎么做的。

  1. 打开文件vi file
  2. 显示行号:set number!:set number
  3. 然后使用行号将行首替换为“#”,如何?

:35,77s/^/#/

注:数字包含在内,行数从35行到77行,都包含将被修改。

要取消注释/撤销它,只需使用:35,77s/^#//

如果你想在每一行代码后添加一个文本单词作为注释,你也可以使用:

:35,77s/$/#test/(适用于Python等语言)

:35,77s/;$/;\/\/test/(用于Java等语言)

学分/引用:

  1. https://unix.stackexchange.com/questions/84929/uncommenting-multiple-lines-of-code-specified-by-line-numbers-using-vi-or-vim < a href = " https://unix.stackexchange.com/questions/84929/uncommenting-multiple-lines-of-code-specified-by-line-numbers-using-vi-or-vim " > < / >

  2. https://unix.stackexchange.com/questions/120615/how-to-comment-multiple-lines-at-once < a href = " https://unix.stackexchange.com/questions/120615/how-to-comment-multiple-lines-at-once " > < / >

  1. Ctrl + v进入可视块模式
  2. 使用向上和向下箭头选择线条
  3. 输入小写的3我(按小写字母 三次)
  4. (按大写。这将带您进入插入模式。)
  5. 写下你想要添加的文本
  6. Esc
  7. 按下箭头

更灵活的替代方案:

示例:在行开头输入文本XYZ

:%norm IXYZ

这里发生了什么?

  • % ==在每行执行
  • norm ==在正常模式下执行以下键(normal的简称)
  • I ==在行开始插入
  • XYZ ==你想输入的文本

然后你点击输入,它就执行了。

具体到您的要求:

:%norm Ivendor_

你也可以选择一个特定的范围:

:2,4norm Ivendor_

或在选定的可视范围内执行:

:'<,'>norm Ivendor_

或者执行匹配'target'正则表达式的每一行:

:%g/target/norm Ivendor_

我来这里粘贴许多行已经复制的字符串。当使用y复制时,我们可以在插入模式下粘贴,按Ctrl+r,然后立即按。这将与在NORMAL MODE下按p有相同的结果。这叫做从注册表粘贴。

假设缓冲区中有以下文本:

vendor_something


text
to_receive
the_paste
pattern

然后我们可以将光标指向vendor_中的v,并按v,使用l向右移动,直到选择我们想要粘贴到下面的文本中的下划线符号。在此之后,我们可以将光标指向“文本”的开头。(vendor_something下面有两行)并按Ctrl+v。然后I进入插入模式,按3j Ctrl+r Esc。这个序列的结果将是:

vendor_something


vendor_text
vendor_to_receive
vendor_the_paste
vendor_pattern

:, + 3 s / ^ / vendor_ /

另一个例子,我只需要在125行的块中添加两个空格,所以我使用(将光标定位在块的第一行开始):

:., + 125 s / ^ / /

伟大的工作。

如果整个文件都需要更改,

:1,$s/^/vendor_/

如果只需要更改几行,

转到需要更改的第一行,给出命令

:.,ns/^/vendor_/

将n替换为块中最后一行的行号。

或者,

:.,+ns/^/vendor_/

将n替换为需要更改的行数减去1。