我正在尝试编写一个表达式来替换名为testRegex.csv
的文件{"type":"MultiPolygon","coordinates":[[[-74.043886,40.690185 -74.040365,40.700704 -74.040288,40.700644 -74.03995,40.700891]]]}
用这个
{"type":"MultiPolygon","coordinates":[[[[-74.043886,40.690185], [-74.040365,40.700704], [-74.040288,40.700644], [-74.03995,40.700891]]]}
我尝试了以下
sed 's/(\W\d\d[.]\d*[,]\d\d[.]\d*)/[$1],/g' <testRegex.csv >testRegex2.csv
sed 's/(\W\d\d[\.]\d*[\,]\d\d[\.]\d*)/[$1]\,/g' <testRegex.csv >testRegex2.csv
sed 's/(\W\d\d\.\d*\,\d\d\.\d*)/[$1]\,/g' <testRegex.csv >testRegex2.csv
任何人都可以看到为什么这些不起作用?
答案 0 :(得分:2)
尝试以下方法:
sed -E -e 's/([0-9-]+\.[0-9]*,[0-9-]+\.[0-9]*)/[\1],/g' -e 's/,]/]/'
请注意,在某些系统上,您可能需要将-E
选项替换为-r
,这是扩展正则表达式支持的选项。
答案 1 :(得分:0)
我试图解决比接受的答案稍微难一些的问题 - 并且开发了一个答案,它不会改变输出格式中的行。这很难,但可以做到(ERE支持比传统的sed
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
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]]]}
/([^[]\[\[\[)((\[[-+]?[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
。最后的s///
删除了方括号中最后一对新数字后添加的逗号。
请注意,BRE正则表达式不会坚持小数点后的数字;它可以做得更长,以便它(在四个小数点的每一个之后添加额外的[0-9]
)。