BASH:将多线(JSON)块转换为单线串

时间:2013-06-24 10:30:07

标签: json bash

我将JSON输出写入“out”文件,其内容如下所示。

$ cat out

{
    "columns": [
        "Tests",
        "Errors",
        "Mean Test Time (ms)",
        "Test Time Standard Deviation (ms)",
        "TPS",
        "Peak TPS"
    ],
    "status": {
        "description": "Collection stopped",
        "state": "Stopped"
    },
    "tests": [
        {
            "description": "Cheetah client test",
            "statistics": [
                0,
                0,
                "NaN",
                0.0,
                0.0,
                0.0
            ],
            "test": 1
        },
        {
            "description": "Reads 95%",
            "statistics": [
                304000,
                0,
                8.7931875,
                7.948696618436826,
                6907.677974959667,
                13594.0
            ],
            "test": 101
        },
        {
            "description": "Writes 5%",
            "statistics": [
                16000,
                0,
                9.963375,
                9.92775949594747,
                363.5619986820878,
                1638.0
            ],
            "test": 102
        }
    ],
    "totals": [
        320000,
        0,
        8.851696875,
        8.063234652303947,
        7271.239973641756,
        14259.0
    ]
}

我需要与描述块有关的统计数据“读取95%”以下面的格式排列并使用BASH脚本分配给字符串变量。

var=304000,0,8.7931875,7.948696618436826,6907.677974959667,13594.0

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

您需要使用专用的命令行JSON解析器,例如underscore

安装了下划线,您可以:

cat data.json | underscore select '.description, .statistics first-child'| tr -d '[]'

编辑:仅限Sed解决方案(谨慎使用):

sed -rn '/"description": *"Reads 95%",/,/],/{/statistics|description/!{1h; 1!H;};/],/{x;s/ *\n *|^ *|],//gp;};}' out

# gives 304000,0,8.7931875,7.948696618436826,6907.677974959667,13594.0

答案 1 :(得分:0)

我的“纯shell”解决方案在

之下
cat data.json | sed 's/^[ \t]*//;s/[ \t]*$//' | awk  -F ': *' 'BEGIN { RS=",\n\"|\n}," } { gsub(/[\n\]\[\}]/,"",$2); if ($2) { printf("%s,", $2); } }'

答案 2 :(得分:0)

out文件包含解析为JSON的Grinder(一种开源负载测试工具)测试数据

curl -s -X GET http://<localhost>:6373/recording/data' | python -mjson.tool > out

~$ cat out

{
    "columns": [
        "Tests",
        "Errors",
        "Mean Test Time (ms)",
        "Test Time Standard Deviation (ms)",
        "TPS",
        "Peak TPS"
    ],
    "status": {
        "description": "Collection stopped",
        "state": "Stopped"
    },
    "tests": [
        {
            "description": "Cheetah client test",
            "statistics": [
                0,
                0,
                "NaN",
                0.0,
                0.0,
                0.0
            ],
            "test": 1
        },
        {
            "description": "Reads 95%",
            "statistics": [
                304000,
                0,
                8.7931875,
                7.948696618436826,
                6907.677974959667,
                13594.0
            ],
            "test": 101
        },
        {
            "description": "Writes 5%",
            "statistics": [
                16000,
                0,
                9.963375,
                9.92775949594747,
                363.5619986820878,
                1638.0
            ],
            "test": 102
        }
    ],
    "totals": [
        320000,
        0,
        8.851696875,
        8.063234652303947,
        7271.239973641756,
        14259.0
    ]
}

Sed命令:

sed -nr "H;/$name/,/\}/{s/(\})/\1/;T;x;p};/\{/{x;s/.*\n.*//;x;H}" out | sed -e     '1,/statistics/d' | sed -e '/test/,$d' | sed '$d' | sed '/^$/d' | tr "\\n" " " | sed -e 's/[\t ]//g;/^$/d'

给出了以下输出 - 测试“读取95%”的测试统计数据

304000,0,8.7931875,7.948696618436826,6907.677974959667,13594.0

下一个sed命令:

sed -nr "H;/"Reads 95%"/,/\}/{s/(\})/\1/;T;x;p};/\{/{x;s/.*\n.*//;x;H}" out gives

    {
        "description": "Reads 95%",
        "statistics": [
            304000,
            0,
            8.7931875,
            7.948696618436826,
            6907.677974959667,
            13594.0
        ],
        "test": 101
    },
  1. 管道结果1带| sed -e'1,/ statistics / d'给出该行包含“statistics”后的所有行

            304000,
            0,
            8.7931875,
            7.948696618436826,
            6907.677974959667,
            13594.0
        ],
        "test": 101
    },
    
  2. 管道结果2与| sed -e'/ test /,$ d'给出上面的行包含“test”

            304000,
            0,
            8.7931875,
            7.948696618436826,
            6907.677974959667,
            13594.0
        ],
    
  3. 管道结果3与| sed'$ d'删除输出3的最后一行             304000,             0,             8.7931875,             7.948696618436826,             6907.677974959667,             13594.0

  4. 管道结果4带| tr“\ n”“”| sed -e's / [\ t] // g; / ^ $ / d'给出

    304000,0,8.7931875,7.948696618436826,6907.677974959667,13594.0

  5. tr“\ n”“”用空格替换CR(或\ n)和sed -e's / [\ t] // g; / ^ $ / d'删除所有空格和制表符

    注意:我不是这个学科领域的专家,因此这可能不是最有效的解决方案