sed 手册明确指出,可用于替换字符串的可用反向引用编号为 \1 到 \9。我正在尝试解析一个包含 10 个字段的日志文件。
我已经为它形成了正则表达式,但第十场比赛(以及之后的任何比赛)都无法访问。
有没有人有一种优雅的方式来规避 KSH(或任何我可以移植到 shell 脚本的语言)中的这种限制?
sed 手册明确指出,可用于替换字符串的可用反向引用编号为 \1 到 \9。我正在尝试解析一个包含 10 个字段的日志文件。
我已经为它形成了正则表达式,但第十场比赛(以及之后的任何比赛)都无法访问。
有没有人有一种优雅的方式来规避 KSH(或任何我可以移植到 shell 脚本的语言)中的这种限制?
你可以用用户perl -pe 's/(match)(str)/$2$1/g;'
代替 sed 吗?绕过反向引用限制的方法是使用 sed 以外的东西。
另外,我想你可以分两步进行替换,但我不知道你的模式,所以我无法帮助你。
使用 -e 拆分流,只要替换的元素在您拆分它们的组中。当我进行日期拆分以便我可以将日期时间重新组织为一串 14 位数字时,我必须将流拆分 3 次。
echo "created: 02/05/2013 16:14:49" | sed -e 's/^\([[:alpha:]]*: \)//' -e 's/\([0-9]\{2\}\)\(\/\)\([0-9]\{2\}\)\(\/\)\([0-9]\{4\}\)\( \)/\5\1\3/' -e 's/\([0-9]\{2\}\)\(\:\)\([0-9]\{2\}\)\(\:\)\([0-9]\{2\}\)/\1\3\5/'
20130205161449
您要求的是 shell 脚本解决方案——这意味着您不仅限于使用 sed,对吗?大多数 shell 都支持数组,所以也许您可以将行解析为 shell 数组变量?如果需要,您甚至可以多次解析同一行,在每次传递时提取不同的信息位。
会这样吗?
如果你有GNU awk
,你可以做更多的事情来控制。为此,您将需要match(source,/regex/,array)
构造。
例子:
用于测试的样本输入:
echo "$x"
p1=aaa,p2=bb,p3=cc,p4=dd,p5=ee,p6=ff,p7=gg,p8=hh,p9=ii,p10=jj
sed
工作正常,直到\9
:
echo $x |sed -r 's/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+)(.*)/\1 \2 \3 \4 \5 \6 \7 \8 \9/'
aaa bb cc dd ee ff gg hh ii
sed
加入时打破\10
,它被认为是\1
+ 0
。
echo $x |sed -r 's/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+).*p10=([^,]+)(.*)/\1 \2 \3 \4 \5 \6 \7 \8 \9 \10/'
aaa bb cc dd ee ff gg hh ii aaa0
awk
当添加超过 9 的任何反向引用时进行救援。这里添加了第 10 个引用:
echo "$x" |awk '{match($0,/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+).*p10=([^,]+)(.*)/,a);print a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10]}'
aaa bb cc dd ee ff gg hh ii jj
考虑一个不需要使用正则表达式反向引用的解决方案。例如,如果您有一个简单的字段分隔符,请使用split
,甚至使用 awk 代替 perl 进行处理。