Sed

(Mac 終端) sed 解析 JSON ……我做錯了什麼?

  • July 23, 2021

在 Mac 終端中,我試圖從這個 JSON 響應中解析出“名稱”:

{“created_at”:“2012-08-27T20:04:27Z”,“deleted_at”:null,“id”:21462840,“item_type”:“video”,“name”:“CastingBy-v12 mixed.mov”, “private”:true,“redirect_url”:null,“remote_url”:“http://f.cl.ly/items/3D0P02b3e3p2I/CastingBy-v12%20mixed.mov","source":"Cloud/1.5.4 CFNetwork/520.4.3 Darwin/11.4.0 (x86_64) (MacPro5%2C1)”,“updated_at”:“2012-08-27T20:13:38Z”,“view_counter”:2,“href”:“http:// /my.cl.ly/items/2840”,“icon”:“http://my.cld.me/images/item-types/video.png","subscribed":true,"url":"http ://files.housenyc.com/1I3E2F3C”,“content_url”:“http://files.eeehousenyc.com/1I3Q0Z1E2F3C/CastingBy-v12%20mixed。mov”,“download_url”:“http://files.eeehousenyc.com/1I3Q0F3C/download/CastingBy-v12%20mixed.mov","gauge_id":null}

我正在使用

sed 's/{.*?"name":"\(.+?\)".*/\1/'

但它返回整個字元串。

我希望它回來

CastingBy-v12 mixed.mov

這是您要查找的表達式:

sed -e 's/^.*"name":"\([^"]*\)".*$/\1/' infile

結果是:

CastingBy-v12 mixed.mov

在你的有幾個錯誤:

  • sed只能使用貪婪表達式:並且是不正確的.*?.+?
  • +必須逃脫。
  • 用於[^"]*避免正則表達式匹配到字元串的最後一個雙引號。

僅使用 sed 解析 json 與解析 HTML 一樣有問題 - 簡而言之:由於元素可以嵌入其他元素並且正則表達式不支持遞歸,因此僅使用正則表達式基本上不可能正確解析。

這裡有一個解析和驗證 json 的 PCRE 解決方案:https ://stackoverflow.com/questions/2583472/regex-to-validate-json - 我沒有使用或測試過它,所以我必須接受作者的話它可以工作…但是PCRE 做了很多不在 sed 支持的基本或擴展正則表達式中的事情。

在任何情況下,IMO 你最好使用 perl 或 python 或 awk 以及這些語言的 json 解析庫之一,或專門的 json 解析工具 - 這裡提到了幾個:

https://stackoverflow.com/questions/3858671/unix-command-line-json-parser

它們中的任何一個都可用於從 JSON 輸入中提取數據以用於 shell 腳本。或者你可以用那種語言編寫你的整個程序。

例如,將您的 json 數據通過管道傳輸到 python -mjson.tool 會導致:

$ echo "JSONDATAHERE" | python -m json.tool
{
"content_url": "http://files.eeehousenyc.com/1I3Q0Z1E2F3C/CastingBy-v12%20mixed.mov",
"created_at": "2012-08-27T20:04:27Z",
“deleted_at”:空,
"download_url": "http://files.eeehousenyc.com/1I3Q0F3C/download/CastingBy-v12%20mixed.mov",
“儀表ID”:空,
"href": "http://my.cl.ly/items/2840",
"圖示": "http://my.cld.me/images/item-types/video.png",
“身份證”:21462840,
"item_type": "影片",
"name": "CastingBy-v12 mixed.mov",
“私人”:真的,
“redirect_url”:空,
"remote_url": "http://f.cl.ly/items/3D0P02b3e3p2I/CastingBy-v12%20mixed.mov",
“來源”:“Cloud/1.5.4 CFNetwork/520.4.3 Darwin/11.4.0 (x86_64) (MacPro5%2C1)”,
“訂閱”:是的,
“updated_at”:“2012-08-27T20:13:38Z”,
"url": "http://files.housenyc.com/1I3E2F3C",
“view_counter”:2
}

然後您可以像這樣將其通過管道傳輸到 sed 中:

$ echo "JSONDATAHERE" | python -m json.tool | sed -n -e '/"name":/ s/^.*"\(.*\)".*/\1/p'
CastingBy-v12 mixed.mov

依靠 regexp 的貪婪特性,sed 腳本"提取"包含"name":.

引用自:https://unix.stackexchange.com/questions/46465