Мне нужно получить значение после определенного слова

Мне нужно получить значение после определенного слова

Мне нужно получить значение «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, например, на ).

Связанный контент