在Vim中替换上面的行中的文本

时间:2009-05-07 11:36:51

标签: vim vi

如何将这十个字符与特定模式匹配的行的前十个字符替换为上一行中的前十个字符?

编辑:目前尚不清楚我是否要求替换匹配可能出现在该行内任何位置的前十个字符,因此如果处理此案例,请在答案中记下(请将此案例称为B和预期的一个案例A?)

6 个答案:

答案 0 :(得分:4)

Prehaps:

:%s/^\(.\{10}\)\(.*\n\)abcdefghij\(.*\)/\1\2\1\3/

其中'abcdefghij'是第二行的10个字符串

答案 1 :(得分:3)

这样的事情会起作用:

%s/^.\{10\}/\=strpart(get(getbufline("", line(".")-1), 0, ""), 0, 10)/

其中^.\{10\}是您的实际模式。

%s/                      # substitute all lines matching…
^.\{10\}                 # your pattern
/                        # …with…
\=                       # an expression:
strpart(                 # gets the part of a string
  get(                   # gets an element of a list
    getbufline(          # gets a list of lines from the current buffer
      "", line(".")-1)   # getbufline() the line before the current line
  , 0, "")               # get() first line in buffer, default to ""
, 0, 10)                 # strpart() first ten characters
/                        # …end of substitution

答案 2 :(得分:3)

:2,$g/<pattern>/s/^.\{10}/\=strpart(getline(line(".")-1),0,10)
  • 2,$是我们的范围(因为第一行没有前一行)
  • g//允许您在与给定模式匹配的行上运行命令。
  • s/^.\{10}/将替换一行的前10个字符
  • \=允许您在:s//
  • 中替换vim表达式的结果
  • line(".")是当前行号
  • getline(line(".")-1)是上一行的文字
  • strpart(getline(line(".")-1),0,10)是前一行的前10个字符

例如2,$g/frog/s/^.\{10}/\=strpart(getline(line(".")-1),0,10)会改变:

I like eating mangos
before frying frogs legs
I wish I had a puppy
She gave Dad a frog

对此:

I like eating mangos
I like eating frogs legs
I wish I had a puppy
I wish I had a frog

答案 3 :(得分:2)

如果我有类似的复杂动作,我通常使用q命令录制宏。像(未经测试)的东西:

/<pattern>
qq
10x
k
10yl
j
P
n
q

然后重复发出该宏为@q,可选择以计数为前缀。

答案 4 :(得分:1)

您可以使用搜索和替换:

:7,9 s/foo/bar/c

此示例在每次出现'foo'时从第7行到第9行搜索,并将其替换为'bar',要求每次点击确认。如果您不想确认,请将c放在最后。根据您的需要选择范围,这可以让您找到您想要的地方

答案 5 :(得分:1)

仅使用vim的动作和yanking /粘贴..给出文件内容..

1234567890abcdef
qwertyuiopasdfgh

将光标放在q 10x上,文件变为:

1234567890abcdef
asdfgh

将光标移动到第一行(使用k将执行此操作),然后执行10yl(向右移动10个字符)

然后向下移动一行j,并粘贴P(大写,粘贴到光标下),文件变为:

1234567890abcdef
1234567890asdfgh

简而言之,从q:

上的光标开始
10xk10yljP

..您可以粘贴,或指定to a macro

如果通过覆盖粘贴有明显的快捷方式会更短,但我找不到这样的东西

另一个选择是令人难以置信的模糊搜索/替换..

视线选择两个目标线,然后运行以下搜索和替换:

:'<,'>s/\(\(.\{10\}\).*\)\n\(.\{10\}\)\(.*\)$/\1\r\2\4/

基本上它抓住了..

  • \1 - 整个第一行
  • \2 - 前10个字符(嵌套组中)
  • 换行
  • \3 - 第二行的前十个字符
  • \4 - 第二行的其余部分

然后它将两行构造为\1\n\2\4 - 完成第一行,换行符,第一行的前10个字符,第二行的剩余部分

相关问题