2016-11-01 53 views
2

我試圖刪除線與現有線路的最後一個字符用的sed:如何刪除前行的最後一個字符用sed的

我有一個JSON文件:

{ 
"name":"John", 
"age":"16", 
"country":"Spain" 
} 

我想刪除所有條目的國家,爲此我必須刪除前一行的json語法的逗號。

我使用這個模式:

sed '/country/d' test.json 
sed -n '/resolved//.$//{x;d;};1h;1!{x;p;};${x;p;}' test.json 

編者按
的OP後來澄清了以下額外要求,這無效現有的一些答案:
- 發生的country屬性應刪除
- 所有級別的對象層次
- 空白的差異應該被容忍

+4

我想知道爲什麼'sed'? 有很多能夠解析JSON的工具。考慮使用'jq','perl','php',或者內置JSON解析器的東西。 –

+0

我更喜歡SHELL,因爲我將在jenkins工作中使用該命令。 –

+1

「我更喜歡SHELL」:有些工具可以用來從shell腳本操作json。例如jq。 – njzk2

回答

2

使用正確的JSON解析器如jq一般最好的選擇 e(見下文),但如果安裝實用程序不是一個選項,請嘗試此操作GNUsed命令

$ sed -zr 's/,\s*"country":[^\n]+//g' test.json 
{ 
"name":"John", 
"age":"16" 
} 
  • -zNUL s,這在此情況下意味着,整個文件被讀取一次,這使交叉線替換將輸入到記錄。

  • -r使擴展正則表達式爲更多現代語法與更多的功能。

  • s/,\n"country":\s*//g替換逗號出現的所有隨後空格組成的(可能爲空)運行(可能包括一個換行),然後通過"country"該行的與空字符串,即端,實際上刪除了匹配的字符串。

    • 注意,這假定沒有其它屬性或關閉}如下例如在同一行上一個country屬性。

爲了證明基於jq一個更可靠的解決方案。

Bertrand Martel's helpful answer包含在輸入對象分層結構的任何地方替換country屬性的jq溶液,其中,但是,並沒有解決的要求(加入)。

jq更高尚未發佈的版本比v1.5.2,一個內置walk/1功能將可用,可實現以下簡單的解決方案:

# Walk all nodes and remove a "country" property from any object. 
jq 'walk(if type == "object" then del (.country) else . end)' test.json 

v1.5.2及以下,你可以定義walk自己的簡化字:

jq ' 
    # Define recursive function walk_objects/1 that walks all objects in the 
    # hierarchy. 
    def walk_objects(f): . as $in | 
    if type == "object" then 
     reduce keys[] as $key 
     ({}; . + { ($key): ($in[$key] | walk_objects(f)) }) | f 
    elif type == "array" then map(walk_objects(f)) 
    else . end; 
    # Walk all objects and remove a "country" property, if present. 
    walk_objects(del(.country)) 
' test.json 
+0

這是隻適用於第一個關鍵,而不是所有的休息,我有多個條目與國家鍵 –

+0

@YasserB .:只需添加'g'選項來全局替換(_all_ occurrences) - 查看我的更新。 – mklement0

+0

謝謝whatif在「國家」之前有空間 –

1

您可以使用JSON解析器像jq解析JSON文件。下面將在result.json返回文檔沒有country場和寫入新文件:

jq 'del(.country)' file.json > result.json 
+0

這不適用於多個/嵌套密鑰 –

+0

@YasserB。你的json文件沒有多個或嵌套的鍵。 – njzk2

+0

檢查這個要點:https://gist.github.com/akinaru/120cb4583b60b0dc77f1012bc5f4a9f8爲一個完整的例子 –

2

正如指出的之前你真的應該考慮使用JSON解析器來解析JSON。

當那個據說可以發出聲音的整個文件,刪除新行,然後accordantly更換 :

$ sed ':a;N;$!ba;s/\n//g;s/,"country"[^}]*//' test.json 
{"name":"John","age":"16"} 

擊穿:

:a;     # Define label 'a' 
    N;    # Append next line to pattern space 
    $!ba;   # Goto 'a' unless it's the last line 
s/\n//g;   # Replace all newlines with nothing 
s/,"country"[^}]*// # Replace ',"country...' with nothing 
2

這可能爲你工作(GNU SED):

sed 'N;s/,\s*\n\s*"country".*//;P;D' file 

將兩行讀入模式空間並刪除替換字符串。

N.B.允許在該行的任何一側留出空間。

相關問題