簡體   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