Предполагая, что весь встроенный 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)"
}
}
]
}