繁体   English   中英

在sed中使用正则表达式查找替换

[英]find replace using regex in sed

我正在尝试编写一个表达式来替换名为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

任何人都可以看到为什么这些不起作用?

请尝试以下方法:

sed -E -e 's/([0-9-]+\.[0-9]*,[0-9-]+\.[0-9]*)/[\1],/g' -e 's/,]/]/'

请注意,在某些系统上,您可能需要将-E选项替换为-r ,这是扩展正则表达式支持的选项。

我试图解决一个比接受的答案稍微难的问题 - 并且开发了一个答案,它不会改变输出格式中的行。 这很难,但可以做到(ERE支持比传统的sed BRE表示更简洁)。

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. ([^[]\\[\\[\\[)这匹配前面不是方括号的三个方括号。 它在替换中变为\\1
  2. ((\\[[-+]?[0-9]+\\.[0-9]+,[-+]?[0-9]+\\.[0-9]+\\], )*)这个有两个捕获,但我真的对外部感兴趣。 内部一个查找一个方括号,后跟一个可能有符号的数字(它坚持使用前面至少一个数字和小数点后一位数),一个逗号,另一个可能有符号的数字,一个紧密的方括号(反斜杠不是是绝对必要的,还有逗号和空格。 这个内部捕获将是\\3 ,并且可以重复零次或多次。 外部捕获捕获了\\3所有重复,并被称为\\2 如果不使用外部捕获,那么内部捕获不会捕获“方括号中的数字对”的最后一次重复,而使用两次捕获,您将获得所有重复。
  3. ([-+]?[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] )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM