Як отримати значення з json об'єкта за допомогою awk або sed

У мене є наступний json

[[email protected] ~]#  echo "$Group_ID"
[ {
  "id" : "e27206c0-aeb6-43db-acda-c4ba43233071",
  "name" : "A1",
  "path" : "/A1",
  "subGroups" : [ ]
}, {
  "id" : "89f3bd6a-33a9-4e02-9fe3-eae660c5a6cf",
  "name" : "Admin_UserGroup",
  "path" : "/Admin_UserGroup",
  "subGroups" : [ ]
}, {
  "id" : "cdc2bce5-c3bb-4b88-bdaf-d87b8bb6c644",
  "name" : "Group104",
  "path" : "/Group104",
  "subGroups" : [ ]
}, {
  "id" : "a0d749f2-ab6c-4c27-ad55-3357eaab9527",
  "name" : "Group105",
  "path" : "/Group105",
  "subGroups" : [ ]
}, {
  "id" : "fbf99c34-d50d-408b-8d19-9713f9af3e3a",
  "name" : "Group106",
  "path" : "/Group106",
  "subGroups" : [ ]
}, {
  "id" : "ebd8336f-4017-4fb1-8035-153ae1d9ba37",
  "name" : "Group201",
  "path" : "/Group201",
  "subGroups" : [ ]
}, {
  "id" : "38f4aef7-caf0-4430-9e61-1ae7026e872f",
  "name" : "Group202",
  "path" : "/Group202",
  "subGroups" : [ ]
}, {
  "id" : "436a0f4a-8b1b-4d7d-a014-fcec3513644e",
  "name" : "Group203",
  "path" : "/Group203",
  "subGroups" : [ ]
}, {
  "id" : "41962c5f-e7e9-4748-b81f-e3f1880b78de",
  "name" : "Sure_Groups",
  "path" : "/Sure_Groups",
  "subGroups" : [ {
    "id" : "593dfe69-1ed8-4649-bde4-a277166333f8",
    "name" : "Test1",
    "path" : "/Sure_Groups/Test1",
    "subGroups" : [ ]
  } ]
}, {
  "id" : "6856b69b-9113-46e1-90c6-f34548625278",
  "name" : "UG_1",
  "path" : "/UG_1",
  "subGroups" : [ ]
}, {
  "id" : "6496a0fe-b41f-4f0f-9eb9-5ef749c9130a",
  "name" : "UG_12",
  "path" : "/UG_12",
  "subGroups" : [ ]
}, {
  "id" : "71a5f5ae-bf91-4cdf-ab3c-c09ca15080d6",
  "name" : "UG_1456",
  "path" : "/UG_1456",
  "subGroups" : [ ]
}, {
  "id" : "385ea518-1d40-45f7-afcd-c0488ff02e97",
  "name" : "UG_26",
  "path" : "/UG_26",
  "subGroups" : [ {
    "id" : "a4064e3a-e2e3-47bb-99b8-9f7fadb0bc20",
    "name" : "Test1",
    "path" : "/UG_26/Test1",
    "subGroups" : [ ]
  } ]
}, {
  "id" : "9c5efedc-b901-4dcf-bbc8-8ddeaa5d84f7",
  "name" : "UG_266",
  "path" : "/UG_266",
  "subGroups" : [ ]
}, {
  "id" : "c5eb3064-752c-4f7c-b4f1-ac59f50397dd",
  "name" : "Usergroup_01",
  "path" : "/Usergroup_01",
  "subGroups" : [ ]
}, {
  "id" : "d39dc10c-558b-433e-82b4-e01a8f1d8998",
  "name" : "Usergroup_02",
  "path" : "/Usergroup_02",
  "subGroups" : [ ]
} ]

Як отримати певні дані за допомогою awk або sed .Я повинен отримати дані, де name = "Admin_UserGroup" ?

EDIT # 1

Завдяки Hossein Vatani за його відповідь, і ось останні команди:

$ /opt/keycloak/bin/kcadm.sh get groups -r T0_Realm > Group.json
$ GROUP_ID_TEMP=$(grep -B1 -A0 '"name" : "Admin_UserGroup"' Group.json)
$ GROUP_ID=$(echo $GROUP_ID_TEMP | cut -d : -f2 | awk -F\" '{print $2}')
3
з Python я вже зробив це, але в сервері Python не буде доступна.
додано Автор Sameer Kanade, джерело
Я очікую, що перекладач-пітон буде присутній на більшості систем сьогодні. Якщо це так, ваша проблема має тривіальне рішення.
додано Автор peppy, джерело
Це позначено як дублікат, але це не дублікат, оскільки питання стосується awk і sed.
додано Автор William Wong, джерело

5 Відповіді

Використовуючи jq :

$ printf '%s\n' "$Group_ID" | jq '.[] | select(.name == "Admin_UserGroup")'
{
  "id": "89f3bd6a-33a9-4e02-9fe3-eae660c5a6cf",
  "name": "Admin_UserGroup",
  "path": "/Admin_UserGroup",
  "subGroups": []
}

При цьому вибираються всі об'єкти масиву, ключ name яких відповідає значенню Admin_UserGroup .

9
додано
@SubodhJoshi Ну, клієнт отримає код, який буде нестабільним замість цього.
додано Автор Tejaswi Yerukalapudi, джерело
@SubodhJoshi JSON - це структурований формат документа в тому ж жанрі, що і XML. Розбір таких документів з чим-небудь іншим, ніж виділений парсер, є схильним до помилок. JSON має правила щодо кодування та цитування даних, де йдуть ключі та де дозволено нові рядки тощо.
додано Автор Tejaswi Yerukalapudi, джерело
@ Pac0 Я погоджуюся, що awk не обмежується регулярними виразами. Я не згоден з тим, що awk добре підходить для аналізу в JSON.
додано Автор Tejaswi Yerukalapudi, джерело
@slm Хоча я згоден з вашим коментарем, застосованим до sed, я не згоден з awk, який далеко не обмежується регулярними виразами.
додано Автор PaulP1975, джерело
JSON є структурованими даними, використовуючи інструменти, які не знають про структуру (awk, sed), ви ризикуєте створити відповідний регулярний вираз, що є дуже крихким і не вдасться, тому що не приймаєте до уваги, що дані JSON структуровані.
додано Автор Patrick Szalapski, джерело
@ Pac0 - справедлива точка.
додано Автор Patrick Szalapski, джерело
означає, якщо це можна досягти за допомогою sed або awk , це буде нестабільно?
додано Автор Sameer Kanade, джерело
Для мене JQ не можна використовувати в якості клієнта не дозволяють встановлювати будь-які сторонні API в виробничому середовищі
додано Автор Sameer Kanade, джерело

Відповідно до вашого розгляду основних команд, якщо файл має структуру, як показано, grep може допомогти вам

$ grep -B2 -A3 '"name" : "Admin_UserGroup"' File

але якщо все в одному рядку:

$ sed -E 's/\},\s*\{/\},\n\{/g' File | grep  '"name" : "Admin_UserGroup"'

Використовуючи оригінальний приклад, ви повинні використовувати моє рішення так:

$ echo "$Group_ID" | grep ...
4
додано
Чи можна використовувати те ж саме для sed, а не за допомогою File?
додано Автор Sameer Kanade, джерело
Структура JSON буде такою ж, але позиція запису може змінитися.
додано Автор Sameer Kanade, джерело
як передати змінну $ Group_ID в цю команду, а не файл? і що таке Json у вашій другій команді?
додано Автор Sameer Kanade, джерело
вибачте, я виправив
додано Автор Paul Harrison, джерело
sed міг би це зробити, але він ускладнюється, і я вважаю, що sed має інший обов'язок, і ваша проблема пов'язана з обов'язком grep .
додано Автор Paul Harrison, джерело

Ви можете використовувати JSON.awk:

awk -f JSON.awk -v file1.json file2.json

https://github.com/step-/JSON.awk

3
додано
потрібно копіювати у відповідях весь джерело кожного інструменту, який може виконувати завдання?
додано Автор PaulP1975, джерело
@JeffSchaller так, це стосувалося вашого коментаря. Дякуємо за відповідь та посилання. Я тільки що зробив (очікує) редагування, щоб включити джерело у відповідь. Я боявся, що це було занадто довго, але я забув, що кодові блоки використовують смуги прокручування.
додано Автор PaulP1975, джерело
@ Pac0 - я відмовився від редагування b/c, що файл AWK.json - це 259 рядковий сценарій.
додано Автор Patrick Szalapski, джерело
@ Pac0 - так, вам потрібно покласти JSON.awk на кожну систему, де ви захочете її використовувати.
додано Автор Patrick Szalapski, джерело
Щоб бути повним (автономним) відповіддю, код повинен бути тут, у полі Відповідь, а не посилання.
додано Автор javanix, джерело
@ Pac0 або, якщо ви мали на увазі, що як відповідь на мій коментар, відповіді повинні містити необхідну інформацію, щоб хтось міг його взяти до своєї системи і використовувати її. Системи (повинні) мають awk встановлені, або ж це черепахи аж до ручного написання власного компілятора. Див. Довідковий центр щодо Чому і як видалено деякі відповіді? і Чому відповіді більше не приймаються з мого облікового запису? , які відбивають відповіді лише на посилання.
додано Автор javanix, джерело
OP відхилено jq , оскільки це "API" третьої сторони. Я думаю, що JSON.awk так само багато, як "третій учасник api", хоча і у вигляді сценарію замість c.
додано Автор Frank, джерело

З останніми версіями ksh93 ви можете розібрати дані json в складову змінну ksh93 з read -m json :

print -r -- "$Group_ID" | IFS= read -rm json v
for ((i = 0; i < ${#v[@]}; i++)); do
  if [[ ${v[i].name} = Admin_UserGroup ]]; then
    print -r -- "${v[i]}"
  fi
done

Він виводить:

(
        id=89f3bd6a-33a9-4e02-9fe3-eae660c5a6cf
        name=Admin_UserGroup
        path=/Admin_UserGroup
        typeset -C subGroups
)

Замість print -r - "$ {v [i]}" можна надрукувати $ {v [i] .path} або будь-яку іншу інформацію з цього з'єднання змінної.

2
додано
@SubodhJoshi, так, як я вже сказав, це для оболонки ksh93 (останні версії: ksh93v і новіші), а не оболонка bash . Більшість синтаксису та функцій bash було скопійовано з ksh, однак це далеко не повний клон. Зокрема, bash не підтримує складні змінні ksh.
додано Автор Stéphane Chazelas, джерело
Ця помилка -> -bash: синтаксична помилка біля несподіваного токена ('`
додано Автор Sameer Kanade, джерело
Чи потрібно встановлювати нову бібліотеку?
додано Автор Sameer Kanade, джерело
$ awk '{if($0~/"AdminUserGroup"/) {NR=NR-1;print $0; NR=NR+2;print $0; } }'file1

Таким чином ми можемо надрукувати інформацію про рядки біля шуканого рядка. Крім того, я думаю, замість того, щоб друкувати його, ми можемо розмістити всіх тих, що знаходяться всередині масиву, також:

$ awk '{if($0~/"AdminUserGroup"/) {NR=NR-1;arr[$i]=(print $0);i=$((i+1)); \
    NR=NR+2; arr[$i]=(print $0); } }'file1.

Тоді ми можемо використовувати деталі масиву.

0
додано
Як передати змінну замість файлу?
додано Автор Sameer Kanade, джерело
ІТ КПІ - JavaScript
ІТ КПІ - JavaScript
504 учасників

співтовариство javascript розробників в Telegram