извлечь конкретное значение ключа из json в bash, если ключ совпадает - PullRequest
0 голосов
/ 18 января 2019

У меня есть контент json (output.json)

{"project": {"id": "A", "content": [{"name": "XYZ", "location": "Berlin", "comments":""}, {"name": "ABC", "location": "NewYork", "comments": "Hwllo"}, {"name": "DEF", "location": "Paris", "comments": "Success"}]}}

Я бы хотел извлечь ключ location со значением, когда name соответствует, скажем, ABC из вышеуказанного json, используя команды bash или shell

Я пробовал что-то вроде ниже, что дает содержание в фигурных скобках. но не уверен при поиске конкретного ключа.

cat output.json | grep -o -e "{.*}"

Ожидаемые результаты: если name соответствует ABC, получить вывод как "location":"NewYork"

Есть предложения по дальнейшей обработке?

Ответы [ 4 ]

0 голосов
/ 19 января 2019

Пожалуйста, используйте JSON-анализатор для обработки JSON.
С Xidel это так же просто, как:

xidel -s output.json -e '($json//content)()[name="ABC"]/location'

В качестве альтернативы:

xidel -s output.json -e '$json/(.//content)()[name="ABC"]/location'

or in full:

xidel -s output.json -e '$json/project/(content)()[name="ABC"]/location'

Выше приведено обозначение XPath ( пример # 11, чтение JSON ). Точечная запись (например, jq) также возможна:

xidel -s output.json -e '($json).project.content()[name="ABC"].location'

[править]
Приведенные выше команды выводят NewYork, и я только что понял, что для вывода требуется "location":"NewYork". Xidel тоже может это сделать:

xidel -s output.json -e '($json//content)()[name="ABC"]/concat("""location"":""",location,"""")'

[/ править]

0 голосов
/ 18 января 2019

Для извлечения из json вы должны использовать jq, если можете. По словам авторов, «jq - это как sed для данных JSON» (источник) .

В вашем случае это должно быть:

$ jq -r '.project' output.json | jq -r '.content' | jq '.[] | select(.name=="ABC")' | jq -r '.location'

Вывод будет:

NewYork

Чтобы получить вывод, который вам нужен, так:

"location":"NewYork"

Вы можете использовать:

echo "\"location\":$(jq -r '.project' output.json | jq -r '.content' | jq '.[] | select(.name=="ABC")' | jq '.location')"

Прежде чем использовать jq, вы должны установить его на Debian и Ubuntu:

$ sudo apt install jq

для других ОС вы должны проверить этот сайт .

0 голосов
/ 18 января 2019

Использование Perl

$ perl -0777 -lne ' while(/"name":\s+"ABC",\s+"location":\s+(\S+)/msg) { print "$1\n" } ' output.json
"NewYork",
$ cat output.json
{"project": {"id": "A", "content": [{"name": "XYZ", "location": "Berlin", "comments":""}, {"name": "ABC", "location": "NewYork", "comments": "Hwllo"}, {"name": "DEF", "location": "Paris", "comments": "Success"}]}}
$
0 голосов
/ 18 января 2019

Возможно, есть лучшие способы сделать это быстрым извращенным способом.

cat output.json | sed 's/"name"/\n"name"/g' | grep '"name"' | awk -F',' '{print $2}'

Добавить | grep <preferred name> также, если необходимо отфильтровать по имени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...