打印两个模式之间并排除与出现的次数相同的模式

问题描述

在两个模式之间(和排除)打印尽可能多的模式

输入文件

$ cat /tmp/file.in
                "3": {
                    "cpumask": "0x000000003C000000","devices": [
                        "Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01","Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01","Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01"
                    ]
                },"2": {
                    "cpumask": "0x0000000000060000",

尝试过但只打印第一次

$ sed '1,/devices/d;/]/,$d'  /tmp/sn310_dev.out
                        "Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01","Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01"

解决方法

理想情况下,您的输入将是 json,但如果这是文件的内容,则 jq 将无法在不调整输入的情况下作为 json 进行处理。幸运的是,不要太多,只需将文件作为字符串读取,“调整它”,解析 fromjson 并获得所需的字段。

$ cat file.in
                "3": {
                    "cpumask": "0x000000003C000000","devices": [
                        "Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01","Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01","Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01"
                    ]
                },"2": {
                    "cpumask": "0x0000000000060000",$ </tmp/file.in jq -Rsr '"{\(sub("\\},$"; "}"))}" | fromjson[].devices[]' >/tmp/sn310_dev.out
$ cat /tmp/sn310_dev.out
Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01
Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01
Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01
Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01
Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01

此处,开关 -R-s 将整个输入作为字符串输入,而 -r 将结果作为原始字符串输出。

"{\(sub("\\},$"; "}"))}"

}, 替换尾随的 } 并将所有内容包裹在 {} 中,使其看起来像一个 json 对象。

fromjson[].devices[]

将 json 对象字符串解析为一个值,并从对象中提取值以及每个值的 devices 属性中的值。

jqplay