我试图解决一个比公认答案稍微困难的问题——并开发了一个不会改变输出格式中的行的答案。这很困难,但可以做到(与传统的sed
BRE 表示法相比,ERE 支持更简洁)。
BRE 符号
sed '/\([^[]\[\[\[\)\(\(\[[-+]*[0-9][0-9]*\.[0-9]*,[-+]*[0-9][0-9]*\.[0-9]*\], \)*\)\([-+]*[0-9][0-9]*\.[0-9]*,[-+]*[0-9][0-9]*\.[0-9]*\)/ {
: redo
s//\1\2[\4],/
t redo
s/,]]]/]]]/
}' <<'EOF'
{"type":"MultiPolygon","coordinates":[[[-74.043886,40.690185 -74.040365,40.700704 -74.040288,40.700644 -74.03995,40.700891]]]}
with this
{"type":"MultiPolygon","coordinates":[[[[-84.043886,40.690185], [-64.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]}
EOF
ERE 符号
sed -E '/([^[]\[\[\[)((\[[-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+\], )*)([-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+)/ {
: redo
s//\1\2[\4],/
t redo
s/,]]]/]]]/
}' <<'EOF'
{"type":"MultiPolygon","coordinates":[[[-74.043886,40.690185 -74.040365,40.700704 -74.040288,40.700644 -74.03995,40.700891]]]}
with this
{"type":"MultiPolygon","coordinates":[[[[-84.043886,40.690185], [-64.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]}
EOF
示例输出
{"type":"MultiPolygon","coordinates":[[[[-74.043886,40.690185], [-74.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]]}
with this
{"type":"MultiPolygon","coordinates":[[[[-84.043886,40.690185], [-64.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]}
ERE的解释
/([^[]\[\[\[)((\[[-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+\], )*)([-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+)/
这可以分为 3 个子正则表达式:
([^[]\[\[\[)
这与前面有方括号以外的其他内容的三个方括号匹配。它变成\1
了替换。
((\[[-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+\], )*)
这有两个捕获,但我真的对外部的感兴趣。内部查找一个方括号,后跟一个可能有符号的数字(坚持在小数点前至少使用一位数,小数点后至少使用一位数),逗号,另一个可能有符号数,右方括号(反斜杠是'不是绝对必要的),还有一个逗号和一个空格。这种内部捕获将是\3
,并且可以重复零次或多次。外部捕获捕获 , 的所有重复\3
,并称为\2
。如果不使用外部捕获,则不是内部捕获仅捕获“方括号中的数字对”的最后一次重复,而通过两次捕获,您将获得所有重复。
([-+]?[0-9]+\.[0-9]+,[-+]?[0-9]+\.[0-9]+)
这捕获了一对用逗号分隔的可能有符号的数字。
替换脚本使用了条件sed
循环:
{
: redo
s//\1\2[\4],/
t redo
s/,]]]/]]]/
}
: redo
设置标签。用方括号括起来的s//\1\2[\4],/
相同信息替换第一个不带括号的“可能有符号的数字对,用逗号分隔”。添加g
后缀没有任何作用;该模式必须适用于先前匹配的文本。因此,如果进行了替代,则t redo
有条件地跳回标签。redo
finals///
删除在方括号中最后一对新数字之后添加的逗号。
请注意,BRE 正则表达式不坚持小数点后的数字;它可以做得更长,这样它就可以了([0-9]
在四个小数点后添加一个额外的)。