この行から「名前」の値を取得する必要があります。
"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
これは入力を受けて「レコード」を分割します(通常ワイヤー)を,
選択し、すべてのレコードをのフィールドに配置し、:
各レコードに2つのフィールドを残します。最初のフィールドの場合終わる"name"
(前の角かっこ/中括弧の説明)で、2番目のフィールドを印刷します:
。
サポートしている二重引用符を削除するには、次のものを使用できます。
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
例:それには適していません)。