我需要從這一行取得「name」的值
"snapshots": [{"name":"sLVZt","user":"comment","current":"n","created":"2015-03-11 05:28:02"},{"name":"ubg9x","user":"test2",{"name":"lo3Qp","user":"test3","current":"y","created":"2015-03-11 06:02:46"}]}
我希望輸出是這樣的
sLVZt
ubg9x
lo3Qp
答案1
假設您的 JSON 文件有效,例如
{"snapshots":[{"name":"sLVZt","user":"comment","current":"n","created":"2015-03-11 05:28:02"},{"name":"ubg9x","user":"test2"},{"name":"lo3Qp","user":"test3","current":"y","created":"2015-03-11 06:02:46"}]}
或(因為非資料空白與格式無關),
{
"snapshots": [
{
"name": "sLVZt",
"user": "comment",
"current": "n",
"created": "2015-03-11 05:28:02"
},
{
"name": "ubg9x",
"user": "test2"
},
{
"name": "lo3Qp",
"user": "test3",
"current": "y",
"created": "2015-03-11 06:02:46"
}
]
}
jq
然後像這樣使用:
$ jq -r '.snapshots[].name' file.json
sLVZt
ubg9x
lo3Qp
name
這會提取數組每個元素中鍵的值snapshots
。
您也可以透過多種方式根據其他按鍵的值輕鬆過濾結果:
$ jq -r '.snapshots[] | select(.current == "y").name' file.json
lo3Qp
$ jq -r '.snapshots[] | select(.current != "n").name' file.json
ubg9x
lo3Qp
答案2
如果您使用的是 Linux 或以其他方式可以存取 GNU grep
,您可以執行以下操作:
$ grep -oP '"name":"\K[^"]+' file
sLVZt
ubg9x
lo3Qp
或者,在 Perl 中:
$ perl -lne 'print join "\n", /"name":"([^"]+)/g' file
sLVZt
ubg9x
lo3Qp
答案3
試試這個,
sed 's/,/\n/g' file | awk -F '"' '$2~/name/ {print $(NF-1)}'
sLVZt
ubg9x
lo3Qp
答案4
純粹awk
基於 - 的解決方案可能如下所示:
awk -F':' -v RS=',' '$1 ~ /"name"$/ {print $2}' file
這將獲取輸入並分割“記錄”(通常意味著線) 處,
,然後將所有記錄放入 處的欄位中:
,每個記錄留下兩個欄位。如果第一個字段結束在"name"
(這說明前導方括號/大括號)中,列印第二個字段,它是:
.
如果你想要掉支撐雙引號,你可以使用
awk -F':' -v RS=',' '$1 ~ /"name"$/ {gsub("\"","",$2); print $2}' file
更新
由於修改後的範例輸入包含前導"snapshots":
,其中還包含:
但以“不平衡”的方式,因此這將不再起作用。由於我的回答說“純粹awk
基於”,唯一可能的適應將更加複雜,看起來像這樣:
awk '{n=patsplit($0,field,"\"[^\"]*\":\"[^\"]*\""); for (i=1;i<=n;i++) {split(field[i],elem,":"); if (elem[1]=="\"name\"") print elem[2];};}' file
顯然,這遠不如grep
基於 - 的方法優雅,而且可移植性也較差(不適用於mawk
,eg)。