我有一些文本,其中有两列和两行或更多行。第一列名称仅打印一次。此后,对于后续行,它将留空,直到再次更改为止。
e.g。
name1 xxx
zza
yyy
zzz
name2 ggg
xxx
name3 xxx
zza
ggg
yyy
zzz
我想更改上面的内容以在所有行中打印列名,如下所示:
name1 xxx
name1 zza
name1 yyy
name1 zzz
name2 ggg
name2 xxx
name3 xxx
name3 zza
name3 ggg
name3 yyy
name3 zzz
注意:如开头所述,第一列的空白行数是可变的。可以是2以上的任何数字。
如果重复应用,以下模式将起作用:
:%s/\(^\S\+ \)\(.*\n\)\s\+/\1\2\1/
但是,当然,这一次只会改变一行,我必须重复它,直到更新所有匹配。
我的问题:是否有一个命令可以完成上述转换,其中行数是可变的。
答案 0 :(得分:1)
你的模式几乎正常工作,主要问题在于你 替换换行符,这会更改行,这就是您需要的原因 如您所述,多次运行。当你删除下一行时, 光标将跳转它(即使它被替换回来)然后你 无法比拟。
您可以通过仅在相关位置“开始”匹配来轻松解决此问题
部分,\zs
标志非常有用。 \v
是。{
也有助于使模式更具可读性,控制魔力
选项。这应该有效:
:%s/^\v(\S+\s+).*\n\zs\s+/\1
它捕获非空白部分,移动到下一个空行开始和 在那里设置匹配。然后替换为捕获的部分。现在的时候了 光标移动,过程将重复,如果以下行 不会开始空白(例如在新组的开头) 没有任何反应,因为它不匹配。
答案 1 :(得分:0)
您可以将相同的逻辑录制到宏,在本例中为q。
qq:%s/\(^\S\+ \)\(.*\n\)\s\+/\1\2\1/
按返回并再次按q以停止录制宏
@q将运行一次,但如果您知道最大行数(例如:10),则可以运行10 @ q
答案 2 :(得分:0)
使用awk
可以解决这个问题:
:%!awk '{if($2==""){$2=$1;$1=name}else{name=$1};print}'
答案 3 :(得分:0)
如果所有空格都是空格而不是制表符,您可以使用这个小Python脚本解决它:
<强> col.py 强>:
onServerError
然后将文本文件传递给脚本:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import fileinput
for line in fileinput.input():
if not line.startswith(" "):
current = line.split()[0]
print(line, end="")
continue
print(line.replace(" " * len(current), current, 1), end="")
可以使用Python支持编译ViM,因此可以在ViM中使用此类内容。