Мне нужно получить значение «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
Это позволит взять входные данные и разделить «записи» (что обычно означаетлиния) в ,
, а затем все записи в поля в :
, оставляя два поля на запись. Если первое полезаканчиваетсяin "name"
(это учитывает начальные квадратные/фигурные скобки), выведите второе поле, которое является значением после :
.
Если вы хотите избавиться от двойных кавычек, вы можете использовать
awk -F':' -v RS=',' '$1 ~ /"name"$/ {gsub("\"","",$2); print $2}' file
Обновлять
Поскольку ваш измененный пример ввода содержит ведущий "snapshots":
, который также включает в себя :
but в "несбалансированном" виде, это больше не будет работать. Поскольку мой ответ гласил "чисто awk
-based", единственная возможная адаптация будет гораздо более сложной и будет выглядеть примерно так:
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
, например, на ).