我的列表看起来像这样:
Item 1
Subitem 1
Item 2
Item 3
Subitem 1
Subitem 2
Subsubitem 1
Item 4
实际上,每个顶级项目前面都有一个换行符,每个子项目有两个换行符,子子项目有三个,依此类推。我希望它的格式类似于:
Item 1
Subitem 1
Item 2
Item 3
Subitem 1
Subitem 2
Subsubitem 1
Item 4
我在vim中使用的正则表达式是:
第一级:
%s/^$\n\(\t\w\)/\t\1/g
第二级:
%s/^$\n\(\t\t\w\)/\t\1/g
等等。
如果不必为列表的每个级别运行不同的正则表达式,更好的方法是什么?我尝试使用vim来做这件事,但任何* nix解决方案对我都没问题。
答案 0 :(得分:1)
这取决于执行正则表达式的内容。 例如。 Sed解析行时不会做的伎俩。如果您使用的是sed,请尝试将其替换为tr:
tr '\n' '\t'
答案 1 :(得分:1)
Perl方式:
input{
file{
path =>"path/to/system1_log_file"
type =>"sys1logs"
}
file{
path =>"path/to/system2_log_files"
type =>"sys2logs"
}
}
output{
if[type]=="sys1logs"{
#output to sys1 index
elasticsearch{host => localhost
index => "sys1"
}
}
if[type]=="sys2logs"{
#output to sys2 index
elasticsearch{host => localhost
index =>"sys2"
}
}
}
使用perl -0777pe 's/\n\K\n+/"\t"x(-1+length $&)/gse'
和GNU tr
:
sed
输出:
tr '\n' '\t' | sed -E 's/([^\t])\t\t/\1\n/g'
答案 2 :(得分:1)
这可以通过:s
和sub-replace-expression(\=
)完成。
:%s/^\n\+/\=repeat("\t",len(submatch(0))-1)/
基本上我们会计算\n
的数量,并用\t
的相同数量替换它们。
:%s/^\n\+/.../g
找到\n
的序列%s/.../\={expr}/g
将匹配替换为表达式{expr}
。submatch(0)
获得第n个子匹配。在这种情况下与\0
或&
相同。repeat({str}, {num})
返回一个字符串,{str}
重复{num}
次。len({str})
获取字符串长度{str}
。len(submatch(0))-1
减少长度,因为我们希望将“好线”保持在不同的行上。如需更多帮助,请参阅:
:h :s
:h sub-replace-expression
:h :repeat()
:h :len()
:h submatch()
答案 3 :(得分:0)
您可以做的一件事是递归使用以下正则表达式:
(?<!\n)\n\t*\n
递归查找并替换此正则表达式的所有匹配项
......依此类推,直到正则表达式无处可匹配。
因此,您不必每次都运行不同的正则表达式,但您仍然需要更改部分替换。你可以编写一个小程序来递归地执行它。