2017-05-10 53 views
1

更換模式我有按照以下格式的行一個JSON文件:與匹配字符串的一部分從相同線在bash

{"id":13, "url":"https://sub.domain.com/path", "dm":"-", "ip":"192.168.0.1"} 
{"id":14, "url":"sub.domain2.com/?param=value", "dm":"-", "ip":"192.168.0.1"} 
{"id":15, "url":"domain.com/path", "dm":"prefilled.com", "ip":"192.168.0.1"} 

,我需要更換「DM」:「 - 」與從同一行各自的領域得到這個輸出:

{"id":13, "url":"https://sub.domain.com/path", "dm":"sub.domain.com", "ip":"192.168.0.1"} 
{"id":14, "url":"sub.domain2.com/?param=value", "dm":"sub.domain2.com", "ip":"192.168.0.1"} 
{"id":15, "url":"domain.com/path", "dm":"prefilled.com", "ip":"192.168.0.1"} 

與任何的bash命令只對具有「DM」的臺詞:「 - 」以優化的方式將文件超過10K的線長

+0

你考慮使用'jq'? – anubhava

+0

我正在調查它。我編輯過,以反映該文件是json事件的日誌,每行一個。 – Jinxmcg

回答

1

隨着GNU或OSX sed fo通過-E [R ERE支持:

$ sed -E 's#(.*"url":"([^"]+\/\/)?([^"/]+).*"dm":")-"#\1\3"#' file 
{"id":13, "url":"https://sub.domain.com/path", "dm":"sub.domain.com", "ip":"192.168.0.1"} 
{"id":14, "url":"sub.domain2.com/?param=value", "dm":"sub.domain2.com", "ip":"192.168.0.1"} 
{"id":15, "url":"domain.com/path", "dm":"domain.com", "ip":"192.168.0.1"} 

隨着GNU AWK的第三個參數匹配():

$ awk 'match($0,/(.*"url":"([^"]+\/\/)?([^"/]+).*"dm":")-(".*)/,a){$0=a[1] a[3] a[4]} 1' file 
{"id":13, "url":"https://sub.domain.com/path", "dm":"sub.domain.com", "ip":"192.168.0.1"} 
{"id":14, "url":"sub.domain2.com/?param=value", "dm":"sub.domain2.com", "ip":"192.168.0.1"} 
{"id":15, "url":"domain.com/path", "dm":"domain.com", "ip":"192.168.0.1"} 
+0

這個作品!但是,有一個問題,只有具有「dm」:「 - 」的行才能做到這一點? – Jinxmcg

+1

感謝您的支持。我編輯了這個問題以反映接受的答案。 – Jinxmcg

+1

你說得對。再次編輯 – Jinxmcg

4

隨着jq-1.5(最新版本ATM),你可以這樣做:

jq 'if .dm == "-" then .dm = (.url|sub("https?://";"")|sub("/.*";"")) else . end' a.json 

說明:

if .dm == "-" ...   # Runs the following only if .dm exists and it's value is "-" 
.dm=(...)     # Assigns to .dm 
.url|sub("^https?://"; "") # Takes .url and replaces http/https:// from the beginning 
...|sub("/.*"; "")   # Replaces everything after the first/(including it) 
+0

看起來像OP有一個隱藏的要求,請參閱[我的回答](http://stackoverflow.com/a/43897717/1745001)下的評論:「如何做到這一點只適用於具有」DM「的行:」 - 「'。 'jq'看起來如何? –

+0

只需用'jq'尋找一個好方法。其實我正要推薦Python,它是Linux終端上最乾淨的方法。給我一些時間。 – hek2mgl

+0

好吧,我真的很感興趣,看看如何/如何'jq'處理這個雖然。 –

0

您可以用sed來做到這一點,但我建議你使用的東西,實際上領會的數據,如果有格式的任何變化:

sed -i -r 's/^(.*"url":")(.*\/\/)?(.*)(\/.*)"-"/\1\2\3\4"\3"/g' your_file 
+0

什麼是'。*?'應該是什麼意思?如果它的目的是尋找某種東西,sed不支持它們。 –

+0

帶擴展正則表達式標籤的'sed'應該支持非貪婪匹配,剛剛測試過它並且能夠按照預期工作 – zwer

+0

不,非貪婪匹配不是ERE的一部分,這是沒有sed支持的PCRE的一部分。如果你得到你期望的輸出,那麼這是出於其他原因。 –