json - 在 Bash 中,如何从日志文件中解析多个换行符分隔的 JSON 对象?

标签 json linux bash grep xargs

我正在解析日志文件并获取结果行(使用 grep),如下所示:

2017-01-26 17:19:40 +0000 docker: {"source":"stdout","log":"I, [2017-01-26T17:19:40.703988 #24]  INFO -- : {\"tags\":\"structured_log\",\"payload\":{\"results\":[{\"baserate\":\"-1\"}]},\"commit_stamp\":1485451180,\"resource\":\"google_price_result_metric\",\"object_id\":\"20170126171940700\"}","container_id":"6ecbf7f64e4c9557e9dd1efbc6666a3c6c53f9cd5c18414ed5633cad8c302e","container_name":"/test-container-b49c8188c3ebe4b93300"}
2017-01-26 17:19:40 +0000 docker: {"container_id":"6ecbf7f64e4c9557e9dd1efbc6666a3c6c53f9cd5c18414ed5633cad8c302e","container_name":"/test-container-b49c8188c3ebe4b93300","source":"stdout","log":"I, [2017-01-26T17:19:40.704364 #24]  INFO -- : method=POST path=/prices.xml format=xml controller=TestController action=prices status=200 duration=1686.51 view=0.08 db=0.62"}

然后,我使用以下命令提取 JSON 对象:

... | grep -o -E "\{.*$"

我知道我可以使用 python -mjson.tool 解析单行,如下所示:

... | grep -o -E "\{.*$"| | grep -o -E "\{.*$"|尾-n1 | python -mjson.tool

但我想解析行(或n行)。我怎样才能在 bash 中做到这一点? (我认为 xargs 应该让我这样做,但我是这个工具的新手,无法弄清楚)

最佳答案

jq可以被告知接受纯文本作为输入,并尝试将提取的子集解析为 JSON。考虑以下示例,使用 jq 1.5 进行测试:

jq -R 'capture("docker: (?<json>[{].*[}])$") | .json? | select(.) | fromjson' <<'EOF'
2017-01-26 17:19:40 +0000 docker: {"source":"stdout","log":"I, [2017-01-26T17:19:40.703988 #24]  INFO -- : {\"tags\":\"structured_log\",\"payload\":{\"results\":[{\"baserate\":\"-1\"}]},\"commit_stamp\":1485451180,\"resource\":\"google_price_result_metric\",\"object_id\":\"20170126171940700\"}","container_id":"6ecbf7f64e4c9557e9dd1efbc6666a3c6c53f9cd5c18414ed5633cad8c302e","container_name":"/test-container-b49c8188c3ebe4b93300"}
2017-01-26 17:19:40 +0000 docker: {"container_id":"6ecbf7f64e4c9557e9dd1efbc6666a3c6c53f9cd5c18414ed5633cad8c302e","container_name":"/test-container-b49c8188c3ebe4b93300","source":"stdout","log":"I, [2017-01-26T17:19:40.704364 #24]  INFO -- : method=POST path=/prices.xml format=xml controller=TestController action=prices status=200 duration=1686.51 view=0.08 db=0.62"}
EOF

...正确产生:

{
  "source": "stdout",
  "log": "I, [2017-01-26T17:19:40.703988 #24]  INFO -- : {\"tags\":\"structured_log\",\"payload\":{\"results\":[{\"baserate\":\"-1\"}]},\"commit_stamp\":1485451180,\"resource\":\"google_price_result_metric\",\"object_id\":\"20170126171940700\"}",
  "container_id": "6ecbf7f64e4c9557e9dd1efbc6666a3c6c53f9cd5c18414ed5633cad8c302e",
  "container_name": "/test-container-b49c8188c3ebe4b93300"
}
{
  "container_id": "6ecbf7f64e4c9557e9dd1efbc6666a3c6c53f9cd5c18414ed5633cad8c302e",
  "container_name": "/test-container-b49c8188c3ebe4b93300",
  "source": "stdout",
  "log": "I, [2017-01-26T17:19:40.704364 #24]  INFO -- : method=POST path=/prices.xml format=xml controller=TestController action=prices status=200 duration=1686.51 view=0.08 db=0.62"
}

关于json - 在 Bash 中,如何从日志文件中解析多个换行符分隔的 JSON 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41904454/

相关文章:

javascript - 如何在 Shopify 上将产品颜色选项分为两个类别 "Essentials"和 "Limited Edition"?

php - 查询应返回整数和字符串 CI

android - 如何仅使用 CLI 在 Linux 上安装 Android SDK?

linux - 重定向 Apache 子域 :80 to 8096

javascript - 无法将 getJSON 中的信息保存到 var 中

json - 使用JSONPath从JSON对象获取单个值

c++ - 如何在 Linux 上的 IDE 中使用 C++ 代码的文档?

regex - 如果遇到其他多个节标题中的任何一个,如何退出Sed中的节模式匹配?

java - 使用 shell 脚本写入程序的标准输入

bash - socat:使用串行端口记录对话