Как использовать jq для форматирования JSON со встроенным, экранированным / строковым JSON (для любых / всех структур)? - PullRequest
0 голосов
/ 06 февраля 2019

Есть много вопросов, которые говорят: «У меня есть такая точная структура JSON, пожалуйста, сделайте мою домашнюю работу для меня и сделайте так, чтобы она имела эту другую точную структуру».Это НЕ один из этих вопросов.

Я хочу увидеть jq скрипты для очистки общих данных.Ниже я опубликую ответ, который работает довольно хорошо для большинства данных, которые я получаю из своих журналов.Но, учитывая, что здесь много умных людей, я хочу посмотреть, что придут другие.

Примечание: Это не дубликат других вопросов, потому что природа каждоговопрос, который я видел на SO, приводит к ответам, которые в значительной степени полезны только для ОП.Ответы на этот вопрос должны быть полезны всем, прибегая к помощи чего-то подобного.Какой-нибудь счастливчик получит репутационную бомбу , как я сделал с моим ответом здесь .

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Выполнение fromjson на всех строках может быть выполнено, например, с использованием walk и ?:

walk(if type == "string" then fromjson? // . else . end)

Оставляя только числовые строки

walk(if type == "string"
     then if tonumber? // false then . 
          else fromjson? // . end
     else . end)
0 голосов
/ 06 февраля 2019

Предполагая, что весь встроенный JSON является минимизированным словарем (как в случае с моим выводом Terraform, выводом AWS cli и журналами AWS), этот один jq творит чудеса.

jq 'walk(if type == "string" and .[0:2] == "{\"" then .=(.|fromjson) else . end)'

Он работает поперебирая объект json, ища строки, начинающиеся с {" и используя подпроцесс для передачи их через fromjson (никогда не выходя из jq).

Я поместил его в функцию bash (jqp)потому что это проще, чем избежать кавычек для псевдонима и гораздо более гибким.Затем я могу использовать его для обработки содержимого файла или буфера обмена.

# This is in my .bash_profile
jqp(){
  jq 'walk(if type == "string" and .[0:2] == "{\"" then .=(.|fromjson) else . end)' "$@"
}
# Here is an event trigger from SNS to Lambda
$ cat event.json
{
    "Records": [
        {
            "EventVersion": "1.0",
            "EventSubscriptionArn": "arn:aws:sns:us-east-1:123456789012:sns-to-slack-shared-services:a70df027-2c7f-492a-840a-633d44fd71a6",
            "EventSource": "aws:sns",
            "Sns": {
                "SignatureVersion": "1",
                "Timestamp": "2019-02-06T15:50:30.028Z",
                "Signature": "GN3712/aWjVLftSzdOcW5Zm32/uvfZKrCcvTmz6Obv/AXbz1xc22sTMYt2vFja7coHGhhO5bG6dz/IbJSx/Zm0U/dVVefWKukFl1umP3av+1JoUbbi+4uHai3k3AwQa3wR4HWjrKKmMt+Tkt/gm7jvhcuojtx+n5oc4S6bMsVq5OmSfAWd2Xd1urTm2zeGCL59nbfhZv+xB4db3dk62FtxVKtFXtvO2pH27+E3vXUvgu2k1c2Kd/Vt/vbYCAA==",
                "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-a70df027-2c7f-492a-840a-633d44fd71a6.pem",
                "MessageId": "a8df3067-c347-55ce-b869-64b2c7c1d0a3",
                "Message": "{\"AlarmName\":\"unauthorized_api_calls_Count-alarm\",\"AlarmDescription\":\"This metric monitors unauthorized API calls\",\"AWSAccountId\":\"123456789012\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 datapoint [5.0 (06/02/19 15:45:00)] was greater than or equal to the threshold (1.0).\",\"StateChangeTime\":\"2019-02-06T15:50:30.023+0000\",\"Region\":\"US East (N. Virginia)\",\"OldStateValue\":\"INSUFFICIENT_DATA\",\"Trigger\":{\"MetricName\":\"unauthorized_api_calls\",\"Namespace\":\"security_rules\",\"StatisticType\":\"Statistic\",\"Statistic\":\"SUM\",\"Unit\":null,\"Dimensions\":[],\"Period\":300,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanOrEqualToThreshold\",\"Threshold\":1.0,\"TreatMissingData\":\"\",\"EvaluateLowSampleCountPercentile\":\"\"}}",
                "MessageAttributes": {},
                "Type": "Notification",
                "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:123456789012:sns-to-slack-shared-services:a70df027-2c7f-492a-840a-633d44fd71a6",
                "TopicArn": "arn:aws:sns:us-east-1:123456789012:sns-to-slack-shared-services",
                "Subject": "ALARM: \"unauthorized_api_calls_Count-alarm\" in US East (N. Virginia)"
            }
        }
    ]
}

# Demonstrate that "$@" in the function allows the use of extra options
$ jqp --indent 4 event.json
{
    "Records": [
        {
            "EventVersion": "1.0",
            "EventSubscriptionArn": "arn:aws:sns:us-east-1:123456789012:sns-to-slack-shared-services:a70df027-2c7f-492a-840a-633d44fd71a6",
            "EventSource": "aws:sns",
            "Sns": {
                "SignatureVersion": "1",
                "Timestamp": "2019-02-06T15:50:30.028Z",
                "Signature": "GN3712/aWjVLftSzdOcW5Zm32/uvfZKrCcvTmz6Obv/AXbz1xc22sTMYt2vFja7coHGhhO5bG6dz/IbJSx/Zm0U/dVVefWKukFl1umP3av+1JoUbbi+4uHai3k3AwQa3wR4HWjrKKmMt+Tkt/gm7jvhcuojtx+n5oc4S6bMsVq5OmSfAWd2Xd1urTm2zeGCL59nbfhZv+xB4db3dk62FtxVKtFXtvO2pH27+E3vXUvgu2k1c2Kd/Vt/vbYCAA==",
                "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-a70df027-2c7f-492a-840a-633d44fd71a6.pem",
                "MessageId": "a8df3067-c347-55ce-b869-64b2c7c1d0a3",
                "Message": {
                    "AlarmName": "unauthorized_api_calls_Count-alarm",
                    "AlarmDescription": "This metric monitors unauthorized API calls",
                    "AWSAccountId": "123456789012",
                    "NewStateValue": "ALARM",
                    "NewStateReason": "Threshold Crossed: 1 datapoint [5.0 (06/02/19 15:45:00)] was greater than or equal to the threshold (1.0).",
                    "StateChangeTime": "2019-02-06T15:50:30.023+0000",
                    "Region": "US East (N. Virginia)",
                    "OldStateValue": "INSUFFICIENT_DATA",
                    "Trigger": {
                        "MetricName": "unauthorized_api_calls",
                        "Namespace": "security_rules",
                        "StatisticType": "Statistic",
                        "Statistic": "SUM",
                        "Unit": null,
                        "Dimensions": [],
                        "Period": 300,
                        "EvaluationPeriods": 1,
                        "ComparisonOperator": "GreaterThanOrEqualToThreshold",
                        "Threshold": 1,
                        "TreatMissingData": "",
                        "EvaluateLowSampleCountPercentile": ""
                    }
                },
                "MessageAttributes": {},
                "Type": "Notification",
                "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:123456789012:sns-to-slack-shared-services:a70df027-2c7f-492a-840a-633d44fd71a6",
                "TopicArn": "arn:aws:sns:us-east-1:123456789012:sns-to-slack-shared-services",
                "Subject": "ALARM: \"unauthorized_api_calls_Count-alarm\" in US East (N. Virginia)"
            }
        }
    ]
}
...