2014-06-17 53 views
0

我有一個捲曲調用查詢JIRA REST API,並返回一個JSON字符串,像下面的(預計在一行):使用SED找引號內,並跳過轉義的引號

{ 
    "expand":"renderedFields,names,schema,transitions,operations,editmeta,changelog", 
    "id":"36112","self":"https://jira.company.com/rest/api/2/issue/36112", 
    "key":"FOO-1218", 
    "fields": 
     {"summary":"the \"special\" field is not returning what is expected"} 
} 

我試着使用這個sed腳本解析出「摘要」字段:

sed 's/^.*summary":"\([^"]*\)".*$/\1/' 

工作正常,如果「摘要」沒有一個逃脫\」裏面它 - 但當然,與逃脫報價均爲我從示例中得到的是:

the \ 

我所需的輸出要麼是:

the \"special\" field is not returning what is expected 

甚至更​​多fancily這樣的:

the "special" field is not returning what is expected 

它不會出現,我可以在SED做了回顧後,有一個簡單的在bash腳本中解決這個問題的方法?

+1

你爲什麼不使用正確的JSON解析器解析JSON – tripleee

+0

@Jordan什麼是你嗎? r預期產出? –

回答

2

你在請求一個用sed寫的JSON解析器。對不起,但這是瘋了。

這裏是一個明智的方式在Python做到這一點的例子:

import requests 
response = requests.get(JIRA_API_ENDPOINT, headers = JIRA_HEADERS) 
obj = response.json() 
obj['fields']['summary'] 

還有Python中的良好JIRA API包裝,稱爲JIRA,蟒蛇。只要使用它,你就不必做任何解析。我以前使用它的效果很好。鏈接:http://jira-python.readthedocs.org/en/latest/

你的同事會感謝你。

+0

* + 1 * for the理智的方式來做到這一點。 –

+0

經過多次嘗試使用sed來做到這一點之後,我想我最終不得不承認它是瘋狂的,最好的解決方案是使用像Python,Perl或其他選項這樣的命令行JSON選項。 –

1

對於雙引號內,你真的要對這些設施的至少一個:

  1. lookarounds(這樣你就可以檢查什麼之前和之後的報價)。
  2. \K(所以你可以放棄開盤報價)
  3. 檢查捕獲組的能力(這樣你就可以匹配整個報價,但只能捕獲裏面的內容)。

通常情況下,你會想是這樣的:

(?<=(?<!\\)")(?:\\"|[^"])*(?=") 

grep -P模式,它採用PCRE,你可以挖掘到更多的功能,比如佔有慾量詞,我會在這裏補充:

(?<=(?<!\\)")(?:\\"|[^"])*+(?=") 

注意,[^"]通常可以跨越多個線,你通常[^"\r\n]控制運行,但無論如何,3210只能一行一行地看。

0

對於這種有限的情況下,你可以使用類似

vnix$ sed -n 's/.*summary":"\(\([^\\"]*\|\\.\)*\)".*/\1/p' file.json 
the \"special\" field is not returning what is expected 

的引號字符串中,雙引號是不允許的,但任何字符是一個反斜槓後立即允許。字符類也不允許反斜槓,以防止反斜槓「泄漏」到錯誤的部分匹配中。角色類之後的重複只是一種優化,以避免不必要的回溯。

任何試圖推廣它的嘗試都會很快變得相當笨拙。 Friedl book有一個例子,它超出了一頁的範圍,僅僅是爲了說明這是徒勞的。

+0

這不適合我,我不知道爲什麼不。我嘗試了(osx),並得到一個空行: 'echo'{「expand」:「renderedFields,names,schema,transitions,operations,editmeta,changelog」,「id」:「36112」,「self」 https://jira.company.com/rest/api/2/issue/36112","key":"FOO-1218","fields":{"summary":"the \「special \」field is not返回所期望的「}}'| sed -n's /.* summary「:」\(\([^ \\「] * \ | \\。\)* \)。*/\ 1/p'' –

+0

我做了一個小小的調整,沒有OSX現在可以測試,所以這是推測性的。是否在尾部表達式中添加'''是否有幫助? (請參閱編輯。) – tripleee

+0

否,仍然從udpated表達式echo「{」expand「:」renderedFields,名稱,架構,轉換,操作,editmeta,changelo g「,」id「:」36112 「 」自我「: 」https://jira.company.com/rest/api/2/issue/36112「, 」關鍵「: 」F OO-1218「, 」田「:{ 」總結「:」 \「特殊\」字段沒有返回預期的「}}」| sed -n's /.* summary「:」\(\([^ \\「] * \ | \\。\)* \)」。*/\ 1/p'' –

0

經過嚴重的苦苦掙扎之後,我已經想出了一個適用於這個特定用例的方法。我convern轉義引號(\「)爲五個下劃線(_)一個更加模糊的字符序列,做正則表達式,然後將其轉換回:

sed -e 's/\\"/_____/g' -e 's/^.*summary":"\([^"]*\)".*$/\1/' -e 's/_____/"/g' 

所以,完整的測試看起來是這樣的:

echo '{"expand":"renderedFields,names,schema,transitions,operations,editmeta,changelo‌​g","id":"36112","self":"https://jira.company.com/rest/api/2/issue/36112","key":"F‌​OO-1218","fields":{"summary":"the \"special\" field is not returning what is expected"}}' | sed -e 's/\\"/_____/g' -e 's/^.*summary":"\([^"]*\)".*$/\1/' -e 's/_____/"/g' 

和輸出是這樣的:

the "special" field is not returning what is expected