синтаксический анализ json только с использованием bash по умолчанию [закрыто]

Я искал и видел много вопросов, похожих на мой, но ни одного ответа удовлетвори меня.

Мой сценарий: я пишу сценарий, который будет запускаться на сервере. У меня есть команда curl, которая возвращает тело json, и я хочу выбрать все значения с определенным ключом, и я могу не использовать какой-либо внешний инструмент для синтаксического анализа json, такого как jq, и у меня даже нет python, просто простая оболочка bash.

, поэтому мой вопрос: как мне это сделать, используя только оболочку по умолчанию?

для одного и того же ключа будет несколько значений, и я хочу создать массив этих значений.

пример json: -

{
     "people":[
                 {
                     "id":"4568734",
                     "name":"suneel"
                 },
                 {
                     "id":"3678976",
                     "name":"adi"
                  }
             ]
   }

если произносится «имя», то мне нужен массив («suneel» «adi»)

Примечание. Никаких внешних инструментов и только команды bash.

-2
задан 21 August 2019 в 07:11

3 ответа

Функция удара как ниже может использоваться:

function jsonValue() {
KEY=$1
num=$2
awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p
}

я сохранил эту функцию как jsonVal и затем получил этот файл с помощью source jsonVal. Можно очень хорошо использовать его в рамках сценария.

Это ожидает два аргумента. Первым аргументом является имя свойства. При необходимости во всех значениях пропустите второй аргумент. Если определенное значение необходимо, можно добавить второй аргумент как показано ниже.

[root@localhost Desktop]# cat data.json | jsonValue id
4568734
3678976
[root@localhost Desktop]# cat data.json | jsonValue id 1
4568734
[root@localhost Desktop]# cat data.json | jsonValue id 2
3678976
[root@localhost Desktop]# cat data.json | jsonValue name
suneel
adi
[root@localhost Desktop]# cat data.json | jsonValue name 1
suneel
[root@localhost Desktop]# cat data.json | jsonValue name 2
adi
[root@localhost Desktop]#

Hope это помогает.

0
ответ дан 23 October 2019 в 05:07

Используя инструменты кроме надлежащих json синтаксических анализаторов всегда будет подвержено ошибкам или проблемам безопасности.

Ваш наилучший вариант: Если у Вас нет инструментов, необходимо сделать работу, попросить, чтобы администратор IT/Сервера установил их.

<час>

Так или иначе, следующее будет работать, по крайней мере, на Ваш пример:

Используя grep -P:

$ curl ... | grep -Po '"name":"\K[^"]*'
suneel
adi

С нормальным grep:

$ curl ... | grep -o '"name":"[^"]*' | cut -d'"' -f4
suneel
adi

, Если Вы имеете "name" где-нибудь за пределами "people", который Вы не хотите, это, очевидно, перестанет работать.

0
ответ дан 23 October 2019 в 05:07

Это - немного излишества, но у меня уже есть приложение, которое читает метаданные Gmail для Повреждения ежедневных файлов резервных копий, сжатых и приложенных до сообщений Gmail. Формат файла подобен Вашему:

SAMPLE RECORD (REFORMATTED):
============================

{u'internalDate': u'1541947153000', 
u'historyId': u'1517343', 
u'payload': 
    {u'mimeType': u'multipart/mixed',
     u'headers': [
        {u'name': u'Return-Path', u'value': u'<me@gmail.com>'}, 
        {u'name': u'Received', u'value': u'from alien (node-ISP. [IPv6.Address])        by smtp.gmail.com with ESMTPSA id x184-v6sm1211487pfx.42.2018.11.11.06.39.15        for <me@gmail.com>        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);        Sun, 11 Nov 2018 06:39:35 -0800 (PST)'}, 
        {u'name': u'Message-ID', u'value': u'<5be83f27.1c69fb81.4f2bc.2906@mx.google.com>'}, 
        {u'name': u'From', u'value': u'root <me@gmail.com>'}, 
        {u'name': u'X-Google-Original-From', u'value': u'"root" <root@gmail.com>'}, 
        {u'name': u'Received', u'value': u'by alien (sSMTP sendmail emulation); Sun, 11 Nov 2018 07:39:13 -0700'}, 
        {u'name': u'Date', u'value': u'Sun, 11 Nov 2018 07:39:13 -0700'}, 
        {u'name': u'to', u'value': u'me@gmail.com'}, 
        {u'name': u'Subject', u'value': u'Daily-alien-Ubuntu-16.04-Backup-2018-11-11-Sunday.tar.gz.64'}
        ]
    }, 
u'snippet': u'', 
u'sizeEstimate': 18340047, 
u'threadId': u'1670336bc9ac099d', 
u'labelIds': [u'IMPORTANT', u'SENT', u'Label_12'], 
u'id': u'1670336bc9ac099d'
}

Вот фрагмент кода из большого сценария удара:

GrepLine () {

#https://askubuntu.com/questions/952467/extracting-a-specific-string-after-a-given-string-from-html-file-using-a-bash-sc

    End1="'"
    Srch2="{u'name': u'Date', u'value': u'"
    Srch3="{u'name': u'Subject', u'value': u'" # sometimes lower-case "subject"
    End3="'}"
    Srch4="u'sizeEstimate': "
    End4=","
    Srch5="u'labelIds': \[u'"
    End5="]"
    Srch6="u'id': u'" 

    # grep allows fast search (compiled C) and supports case insensitivity
    HeaderDate=$(grep -oiPm1 "$Srch2\K[^$End1]+" <<< "$plLine")
    HeaderSubject=$(grep -oiPm1 "$Srch3\K[^$End3]+" <<< "$plLine")
    [[ $HeaderSubject == "" ]] && HeaderSubject="GREP ERROR: Subject blank"

    Size=$(grep -oiPm1 "$Srch4\K[^$End4]+" <<< "$plLine")

    LabelIds=$(grep -oiPm1 "$Srch5\K[^$End5]+" <<< "$plLine")
    LabelIds="${LabelIds//\', u\'/$LabelSep}"
    TrimLen="${#LabelIds}"
    let TrimLen--
    LabelIds="${LabelIds:0:TrimLen}" # Remove trailing '
    # Convert "Label_12" to "Backup", etc.
    ReplaceLabels

    MessageId=$(grep -oiPm1 "$Srch6\K[^$End1]+" <<< "$plLine")

    # Some email messages have 50 extra spaces or more.
    HeaderSubject="${HeaderSubject%% }"

    # Convert HTML to ASCII, eg: Can&#39;t wear the same one
    # Replace external command: Line=$(sed 's/&amp;/\&/g; s/&lt;/\</g; 
    # s/&gt;/\>/g; s/&quot;/\"/g; s/&#39;/\'"'"'/g; s/&ldquo;/\"/g; 
    # s/&rdquo;/\"/g;' <<< "$Line") -- With faster builtin commands.
    HeaderSubject="${HeaderSubject//&nbsp;/ }"
    HeaderSubject="${HeaderSubject//&amp;/&}"
    HeaderSubject="${HeaderSubject//&lt;/<}"
    HeaderSubject="${HeaderSubject//&gt;/>}"
    HeaderSubject="${HeaderSubject//&quot;/'"'}"
    HeaderSubject="${HeaderSubject//&#39;/"'"}"
    HeaderSubject="${HeaderSubject//&ldquo;/'"'}" # TODO: ASCII/ISO for opening quote
    HeaderSubject="${HeaderSubject//&rdquo;/'"'}" # TODO: ASCII/ISO for closing quote

    # Truncate subject to 80 characters or whatever variable is set to
    HeaderSubject="${HeaderSubject:0:$SubjectTruncate}"
    HeaderSubject="${HeaderSubject//|/?}"       # Strip out Yad array separators
    HeaderSubject="${HeaderSubject//\--/==}"    # Yad doesn't like --
#    HeaderSubject="${HeaderSubject//\'/\"}"   # Yad doesn't like
    [[ $HeaderSubject == "" ]] && HeaderSubject="PARSING ERROR: Subject blank"

    # Convert date to YAD format
    HeaderDate=$(date -d "$HeaderDate" +'%Y-%m-%d')

} # GrepLine
0
ответ дан 23 October 2019 в 05:07

Другие вопросы по тегам:

Похожие вопросы: