Как извлечь объект json только с помощью команд basi c, таких как sed / awk в оболочке? - PullRequest
1 голос
/ 15 февраля 2020

Вот так: у меня есть файл json в следующем формате:

{
    "Item": {
        "summary": {
            "B": "ABCDE"
        },
        "name": {
            "S": "sider"
        },
        "age": {
            "N": "1"
        },
        "data": {
            "B": "abcde"
        }
    }
}

Как получить объект "Item" только с помощью существующих команд, таких как sed / awk, без установки каких-либо внешних инструментов в оболочке ?

ожидаемый результат:

{
    "summary": {
        "B": "ABCDE"
    },
    "name": {
        "S": "sider"
    },
    "age": {
        "N": "1"
    },
    "data": {
        "B": "abcde"
    }
}

Ответы [ 3 ]

2 голосов
/ 15 февраля 2020

Как подсказывает Чепнер, вам нужно подвергнуть сомнению ваши ограничения. В некоторых случаях у вас плохая рука, и вам приходится иметь с ней дело. Итак, вот подход sed:

Вот пересмотренное решение с awk. Sed также добавляется для отступа:

awk '  
  /^    }/  { p = 0 ; print  }  
  p == 1 { print } 
  /"Item": {/ { print "   {" ; p = 1 }  
'  | sed 's/^   //'

Первоначально опубликовано это (но заметил, что вывод не соответствует вашим ожиданиям):

sed -n '/^    "Item": {/,/^    }/p'

Приведенный выше подход sed предполагает этот элемент имеет отступ, как у вас в примере ввода выше.

Вот подход, использующий мой любимый jq:

jq '.Item'

Вы можете хорошо проверить, установлен ли на вашей машине python с пакетом json. Вот скрипт python3, который подойдет вам:

#!/usr/bin/env python3

import json
import sys
j = json.load( sys.stdin ) 
print(json.dumps(j["Item"]))
1 голос
/ 15 февраля 2020

Идиоматически, было бы неправильно манипулировать вложенным форматом данных, таким как JSON, с помощью таких инструментов, как sed / awk. Однако, если вы ограничены в своем выборе, тогда лучшим подходом будет следующее:

  1. преобразование многострочного файла в одну строку
  2. с использованием awk / sed extract ваше Item

Вот решение на основе sed:

bash $ <file.json tr '\n' ' ' | sed -E 's/^ *{ *"Item": +//; s/ *}$//'
0 голосов
/ 15 февраля 2020

Это то, что вам нужно:

sed -n '/^    "Item": {/,/^    }/{s/"Item": //;s/^    //;p}'

, которые основаны на решении Марка , сделав две замены для удаления "Item": и отступа за 4 пробела перед p рингтингом .

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