如何将行中间的文本前置到Vim中的多行?

时间:2021-02-07 19:18:21

Say I have ten lines and I want to prepend text to some word that occurs in those lines? It does not have to be at the beginning of the line.

假设我有十行,我想将文本添加到这些行中出现的某些单词?它不必在行的开头。

From:

sdfsd   foo sdfsd
sfsd    foo fsdf
sdfsdf  foo  sdfsdf

to:

sdfsd   bar(foo sdfsd
sfsd    bar(foo fsdf
sdfsdf  bar(foo  sdfsdf

Is it also possible to not only prepend the bar( but actually surround foo with bar(foo)?

是否也可以不仅仅在前面添加条形图(但实际上用条形图(foo)包围foo?

I would also like a quick way to append // comments to multiple lines (C-style comments).

我还想快速将//注释追加到多行(C风格的注释)。

I use Vim/GVim 7.2.

我使用的是Vim / GVim 7.2。

7 个解决方案

#1


Go to the first foo, press Ctrl-v to enter visual block mode and press down until all the lines with foo are marked. Then press Shift-i to insert at the beginning (of the block). When you are finished and press Esc, the inserted characters will be added to each line at the left of the marked block.

转到第一个foo,按Ctrl-v进入可视区块模式并按下直到标记了所有带有foo的行。然后按Shift-i插入(块的)开头。完成后按Esc键,插入的字符将添加到标记块左侧的每一行。

To insert at the end, press again Ctrl-v, move up/down to mark all affected lines and then press End or $ to extend the selection until the end of the lines. Now you can press Shift-a to append at the end of all the lines, just like previously with Shift-i.

要在最后插入,再次按Ctrl-v,向上/向下移动以标记所有受影响的行,然后按End或$将选择范围扩展到行尾。现在你可以按Shift-a追加到所有行的末尾,就像之前使用Shift-i一样。

The visual selection can also be done with normal movement commands. So to comment a whole block in C you could move to the opening brace and type Ctrl-v % Shift-i // Esc.

视觉选择也可以用正常的移动命令完成。因此,要在C中注释整个块,您可以移动到左括号并键入Ctrl-v%Shift-i // Esc。

#2


To answer your first question, the below

回答你的第一个问题,如下

:%s/foo/bar(&)/g

will look for foo, and surround the matched pattern with bar(). The /g will do this multiple times in one line.

将寻找foo,并用bar()包围匹配的模式。 / g将在一行中多次执行此操作。

Since you're just matching foo, you could do a simple :s/foo/bar(foo)/g. The above will work, however, if you decide to match on a regular expression rather than a simple word (e.g. f[a-z][a-z]). The '&' in the above represents what you've matched.

因为你只是匹配foo,你可以做一个简单的:s / foo / bar(foo)/ g。但是,如果您决定匹配正则表达式而不是简单的单词(例如f [a-z] [a-z]),则上述操作将起作用。上面的'&'表示您的匹配。

#3


To prefix a set of lines I use one of two different approaches:

要为一组行添加前缀,我使用两种不同的方法之一:

One approach is the block select (mentioned by sth). In general, you can select a rectangular region with ctrl-V followed by cursor-movement. Once you've highlighted a rectangle, pressing shift-I will insert characters on the left side of the rectangle, or shift-A will append them on the right side of the rectangle. So you can use this technique to make a rectangle that includes the left-most column of the lines you want to prefix, hit shift-I, type the prefix, and then hit escape.

一种方法是块选择(由sth提及)。通常,您可以使用ctrl-V选择一个矩形区域,然后选择光标移动。一旦你突出显示一个矩形,按shift-I将在矩形的左侧插入字符,或者shift-A将它们附加在矩形的右侧。因此,您可以使用此技术制作一个矩形,其中包含您想要前缀的行的最左侧列,单击shift-I,键入前缀,然后单击escape。

The other approach is to use a substitution (as mentioned by Brian Agnew). Brian's substitution will affect the entire file (the % in the command means "all lines"). To affect just a few lines the easiest approach is to hit shift-V (which enables visual-line mode) while on the first/last line, and then move to the last/first line. Then type:

另一种方法是使用替换(如Brian Agnew所述)。 Brian的替换将影响整个文件(命令中的%表示“所有行”)。为了影响几行,最简单的方法是在第一行/最后一行上点击shift-V(启用可视线模式),然后移动到最后一行。然后输入:

:s/^/YOUR PREFIX/

The ^ is a regex (in this case, the beginning of the line). By typing this in visual line mode you'll see '<,'> inserted before the s automatically. This means the range of the substitution will be the visual selection.

^是正则表达式(在这种情况下,是行的开头)。通过在可视线模式下键入它,您将看到在 之前自动插入。这意味着替换的范围将是视觉选择。 ,'>

Extra tip: if your prefix contains slashes, you can either escape them with backslash, or you can use a different punctuation character as the separator in the command. For example, to add C++ line comments, I usually write:

额外提示:如果您的前缀包含斜杠,您可以使用反斜杠转义它们,也可以使用不同的标点字符作为命令中的分隔符。例如,要添加C ++行注释,我通常会写:

:s:^:// :

For adding a suffix the substitution approach is generally easier unless all of your lines are exactly the same length. Just use $ for the pattern instead of ^ and your string will be appended instead of pre-pended.

对于添加后缀,替换方法通常更容易,除非您的所有行都具有完全相同的长度。只需使用$作为模式而不是^,你的字符串将被附加而不是预先填充。

If you want to add a prefix and a suffix simultaneously, you can do something like this:

如果要同时添加前缀和后缀,可以执行以下操作:

:s/.*/PREFIX & SUFFIX/

The .* matches the whole line. The & in the replacement puts the matched text (the whole line) back, but now it'll have your prefix and suffix added.

。*匹配整行。 &替换中的&匹配文本(整行),但现在它将添加您的前缀和后缀。

BTW: when commenting out code you'll probably want to uncomment it later. You can use visual-block (ctrl-V) to select the slashes and then hit d to delete them, or you can use a substitution (probably with a visual line selection, made with shift-V) to remove the leading slashes like this:

BTW:在评论代码时,您可能希望稍后取消注释。您可以使用visual-block(ctrl-V)选择斜杠然后点击d删除它们,或者你可以使用替换(可能使用shift-V制作的视觉线选择)来删除这样的前导斜杠:

:s:// ::

#4


:normal to the rescue!

:救援正常!

:%norm Wibar(

:%norm WEa)

:norm(al) replays the commands as if you had typed them:

:norm(al)重放命令,就好像你输入了它们一样:

W - goes to the next word

W - 转到下一个词

i - starts insertion mode

我 - 开始插入模式

bar( - types the sequence 'bar('

bar( - 键入序列'bar('

Or in one line:

或者在一行中:

:%norm Wibar(ctrlvESCEa)

If you're running Windows then type ctrlq instead of ctrlv.

如果您正在运行Windows,则键入ctrlq而不是ctrlv。

#5


Yet another possibility (probably not-so-useful in your test case, but handy in other situations) is to cordon off the area you want to change with marks.

另一种可能性(在您的测试用例中可能不那么有用,但在其他情况下很方便)是用标记*您想要更改的区域。

  • Put the cursor anywhere in the top line and press 'a
  • 将光标放在顶行的任意位置,然后按“a”

  • Put the cursor anywhere in the last line and press 'b
  • 将光标放在最后一行的任意位置,然后按'b

  • Issue the command :'a,'b s/foo/bar(&)/
  • 发出命令:'a,'b s / foo / bar(&)/

I usually like visual block mode if everything is visible on the screen, and I usually prefer marks if the start and stop are separated by many screens.

如果一切都在屏幕上可见,我通常喜欢视觉块模式,如果开始和停止被许多屏幕分开,我通常更喜欢标记。

#6


Another simple regular expression is:

另一个简单的正则表达式:

%s/^/<text you want to prepend>/

#7


For the C-style comments, use the regexp answer by Brian, and match on line ending $, and insert away.

对于C风格的评论,请使用Brian的正则表达式答案,并在结束$的行上匹配,然后插入。

#1


Go to the first foo, press Ctrl-v to enter visual block mode and press down until all the lines with foo are marked. Then press Shift-i to insert at the beginning (of the block). When you are finished and press Esc, the inserted characters will be added to each line at the left of the marked block.

转到第一个foo,按Ctrl-v进入可视区块模式并按下直到标记了所有带有foo的行。然后按Shift-i插入(块的)开头。完成后按Esc键,插入的字符将添加到标记块左侧的每一行。

To insert at the end, press again Ctrl-v, move up/down to mark all affected lines and then press End or $ to extend the selection until the end of the lines. Now you can press Shift-a to append at the end of all the lines, just like previously with Shift-i.

要在最后插入,再次按Ctrl-v,向上/向下移动以标记所有受影响的行,然后按End或$将选择范围扩展到行尾。现在你可以按Shift-a追加到所有行的末尾,就像之前使用Shift-i一样。

The visual selection can also be done with normal movement commands. So to comment a whole block in C you could move to the opening brace and type Ctrl-v % Shift-i // Esc.

视觉选择也可以用正常的移动命令完成。因此,要在C中注释整个块,您可以移动到左括号并键入Ctrl-v%Shift-i // Esc。

#2


To answer your first question, the below

回答你的第一个问题,如下

:%s/foo/bar(&)/g

will look for foo, and surround the matched pattern with bar(). The /g will do this multiple times in one line.

将寻找foo,并用bar()包围匹配的模式。 / g将在一行中多次执行此操作。

Since you're just matching foo, you could do a simple :s/foo/bar(foo)/g. The above will work, however, if you decide to match on a regular expression rather than a simple word (e.g. f[a-z][a-z]). The '&' in the above represents what you've matched.

因为你只是匹配foo,你可以做一个简单的:s / foo / bar(foo)/ g。但是,如果您决定匹配正则表达式而不是简单的单词(例如f [a-z] [a-z]),则上述操作将起作用。上面的'&'表示您的匹配。

#3


To prefix a set of lines I use one of two different approaches:

要为一组行添加前缀,我使用两种不同的方法之一:

One approach is the block select (mentioned by sth). In general, you can select a rectangular region with ctrl-V followed by cursor-movement. Once you've highlighted a rectangle, pressing shift-I will insert characters on the left side of the rectangle, or shift-A will append them on the right side of the rectangle. So you can use this technique to make a rectangle that includes the left-most column of the lines you want to prefix, hit shift-I, type the prefix, and then hit escape.

一种方法是块选择(由sth提及)。通常,您可以使用ctrl-V选择一个矩形区域,然后选择光标移动。一旦你突出显示一个矩形,按shift-I将在矩形的左侧插入字符,或者shift-A将它们附加在矩形的右侧。因此,您可以使用此技术制作一个矩形,其中包含您想要前缀的行的最左侧列,单击shift-I,键入前缀,然后单击escape。

The other approach is to use a substitution (as mentioned by Brian Agnew). Brian's substitution will affect the entire file (the % in the command means "all lines"). To affect just a few lines the easiest approach is to hit shift-V (which enables visual-line mode) while on the first/last line, and then move to the last/first line. Then type:

另一种方法是使用替换(如Brian Agnew所述)。 Brian的替换将影响整个文件(命令中的%表示“所有行”)。为了影响几行,最简单的方法是在第一行/最后一行上点击shift-V(启用可视线模式),然后移动到最后一行。然后输入:

:s/^/YOUR PREFIX/

The ^ is a regex (in this case, the beginning of the line). By typing this in visual line mode you'll see '<,'> inserted before the s automatically. This means the range of the substitution will be the visual selection.

^是正则表达式(在这种情况下,是行的开头)。通过在可视线模式下键入它,您将看到在 之前自动插入。这意味着替换的范围将是视觉选择。 ,'>

Extra tip: if your prefix contains slashes, you can either escape them with backslash, or you can use a different punctuation character as the separator in the command. For example, to add C++ line comments, I usually write:

额外提示:如果您的前缀包含斜杠,您可以使用反斜杠转义它们,也可以使用不同的标点字符作为命令中的分隔符。例如,要添加C ++行注释,我通常会写:

:s:^:// :

For adding a suffix the substitution approach is generally easier unless all of your lines are exactly the same length. Just use $ for the pattern instead of ^ and your string will be appended instead of pre-pended.

对于添加后缀,替换方法通常更容易,除非您的所有行都具有完全相同的长度。只需使用$作为模式而不是^,你的字符串将被附加而不是预先填充。

If you want to add a prefix and a suffix simultaneously, you can do something like this:

如果要同时添加前缀和后缀,可以执行以下操作:

:s/.*/PREFIX & SUFFIX/

The .* matches the whole line. The & in the replacement puts the matched text (the whole line) back, but now it'll have your prefix and suffix added.

。*匹配整行。 &替换中的&匹配文本(整行),但现在它将添加您的前缀和后缀。

BTW: when commenting out code you'll probably want to uncomment it later. You can use visual-block (ctrl-V) to select the slashes and then hit d to delete them, or you can use a substitution (probably with a visual line selection, made with shift-V) to remove the leading slashes like this:

BTW:在评论代码时,您可能希望稍后取消注释。您可以使用visual-block(ctrl-V)选择斜杠然后点击d删除它们,或者你可以使用替换(可能使用shift-V制作的视觉线选择)来删除这样的前导斜杠:

:s:// ::

#4


:normal to the rescue!

:救援正常!

:%norm Wibar(

:%norm WEa)

:norm(al) replays the commands as if you had typed them:

:norm(al)重放命令,就好像你输入了它们一样:

W - goes to the next word

W - 转到下一个词

i - starts insertion mode

我 - 开始插入模式

bar( - types the sequence 'bar('

bar( - 键入序列'bar('

Or in one line:

或者在一行中:

:%norm Wibar(ctrlvESCEa)

If you're running Windows then type ctrlq instead of ctrlv.

如果您正在运行Windows,则键入ctrlq而不是ctrlv。

#5


Yet another possibility (probably not-so-useful in your test case, but handy in other situations) is to cordon off the area you want to change with marks.

另一种可能性(在您的测试用例中可能不那么有用,但在其他情况下很方便)是用标记*您想要更改的区域。

  • Put the cursor anywhere in the top line and press 'a
  • 将光标放在顶行的任意位置,然后按“a”

  • Put the cursor anywhere in the last line and press 'b
  • 将光标放在最后一行的任意位置,然后按'b

  • Issue the command :'a,'b s/foo/bar(&)/
  • 发出命令:'a,'b s / foo / bar(&)/

I usually like visual block mode if everything is visible on the screen, and I usually prefer marks if the start and stop are separated by many screens.

如果一切都在屏幕上可见,我通常喜欢视觉块模式,如果开始和停止被许多屏幕分开,我通常更喜欢标记。

#6


Another simple regular expression is:

另一个简单的正则表达式:

%s/^/<text you want to prepend>/

#7


For the C-style comments, use the regexp answer by Brian, and match on line ending $, and insert away.

对于C风格的评论,请使用Brian的正则表达式答案,并在结束$的行上匹配,然后插入。