我正在尝试使用vim将层次(xml)文件重新格式化为“每行”文件。
这是一个简化的示例。实际情况是“大”(500k行),条目和组是任意计数。
输入文件:
<group key="abc">
<entry val="1"/>
<entry val="2"/>
<entry val="3"/>
</group>
<group key="xyz">
<entry val="1"/>
<entry val="2"/>
<entry val="3"/>
<entry val="4"/>
<entry val="5"/>
</group>
输出结果:
abc,1
abc,2
abc,3
xyz,1
xyz,2
xyz,3
xyz,4
xyz,5
请注意,我不需要一个魔术表达式即可完成所有这些工作(尽管会膨胀)。我正在努力的部分是获取与每个条目相关联的密钥。我敢肯定有一个很好的习惯来处理这个问题。提前致谢。
我尝试过的一件事可能对其他人有用:
:g/key="\(.*\)"/.;/<\/group/s/<entry /\1,<entry /g
这不起作用,因为范围匹配未延续到替换中。该表达式本质上是寻找pat1,从那里建立一个范围到pat2,然后用pat4替换pat3(但仅在pat1,pat2范围内的实例中)。
:g/pat1/.;/pat2/s/pat3/pat4/g
解决方案
下面的最佳解决方案是通过查找条目,然后向后查找密钥来解决它,这与我上面通过构建范围和多个替换所做的尝试相反。最终有效的方法需要进行一些细微的修改,因此此处将其提供给其他人。繁重的命令是:
:g/entry/?key?,\?t.
:g/entry/norm ddpkJ
:v/entry/d
分解:
搜索所有输入行:
:g/entry/
从那里,向后搜索包含关键字的行,并将其复制到每个条目下方。
?key?,\?t.
再次搜索所有输入行,然后切换到普通模式编辑
:g/entry/norm
交换两行(删除关键行并将其粘贴到组行下方)。向上移动到关键行并连接这两行。
ddpkJ
映射所有键之后,搜索没有条目的所有行并将其删除。
:v/entry/d
如果像我一样有多个层次结构,则可以多次运行前两行。一旦一切都在一行上,就很容易将其清理成所需的最终格式。另一个主要好处是可以轻松地将此解决方案放入脚本中并重新运行
vim -S script.vim data.file
以下将工作
:g/entry/?<group?,?<group?t.
:%norm J
:g/<\//d
:%norm df"f"df"i,<C-v><Esc>f"d$
分解
对于包含的每一行entry
,向后搜索<group
并复制到条目下方的行
:g/entry/?<group?,?<group?t.
<group key="abc">
<entry val="1"/>
<group key="abc">
<entry val="2"/>
<group key="abc">
<entry val="3"/>
<group key="abc">
</group>
<group key="xyz">
<entry val="1"/>
<group key="xyz">
<entry val="2"/>
<group key="xyz">
<entry val="3"/>
<group key="xyz">
<entry val="4"/>
<group key="xyz">
<entry val="5"/>
<group key="xyz">
</group>
加入所有行
:%norm J
<group key="abc"> <entry val="1"/>
<group key="abc"> <entry val="2"/>
<group key="abc"> <entry val="3"/>
<group key="abc"> </group>
<group key="xyz"> <entry val="1"/>
<group key="xyz"> <entry val="2"/>
<group key="xyz"> <entry val="3"/>
<group key="xyz"> <entry val="4"/>
<group key="xyz"> <entry val="5"/>
<group key="xyz"> </group>
删除结束标签
:g/<\//d
<group key="abc"> <entry val="1"/>
<group key="abc"> <entry val="2"/>
<group key="abc"> <entry val="3"/>
<group key="xyz"> <entry val="1"/>
<group key="xyz"> <entry val="2"/>
<group key="xyz"> <entry val="3"/>
<group key="xyz"> <entry val="4"/>
<group key="xyz"> <entry val="5"/>
通过搜索和从引号中删除来修复其余文本。请注意,这<C-v><Esc>
是在命令中添加转义的键序列。
:%norm df"f"df"i,<C-v><Esc>f"d$
abc,1
abc,2
abc,3
xyz,1
xyz,2
xyz,3
xyz,4
xyz,5
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句