从 Shell 中损坏的 JSON 输出中提取值

从 Shell 中损坏的 JSON 输出中提取值

一旦我列出了服务器上的备份文件,它就会向我输出如下输出:

{
    "backupFiles": [
        "XYZ_Backup_2.0.0.0-417_2022_08_14_12_10.gz",
        "XYZ_Backup_2.0.0.0-417_2022_08_13_11_20.gz",
        "XYZ_Backup_2.0.0.0-417_2022_08_13_15_11.gz",
    ],
    "total": 3
}

我将输出存储到一个变量中。现在我怎样才能只获取文件的名称:

XYZ_Backup_2.0.0.0-417_2022_08_14_12_10.gz

答案1

虽然这确实是损坏的 JSON,但它(至少据我所知)是有效的 YAML(它主要是 JSON 的超集,因此很难判断什么是有效的或无效的。我希望它不是。)。

因此,为 YAML 编写的工具可以处理它。我用yq,它只是 的包装器jq,它将 YAML 动态转换为有效的 JSON。所以,所有你能用 做的事情,你也jq可以用 做。yq在你的情况下

<yamldata.txt yq '.backupFiles []'

给你

"XYZ_Backup_2.0.0.0-417_2022_08_14_12_10.gz"
"XYZ_Backup_2.0.0.0-417_2022_08_13_11_20.gz"
"XYZ_Backup_2.0.0.0-417_2022_08_13_15_11.gz"

如果你只想要第一个,

<yamldata.txt yq '.backupFiles[0]'

印刷

"XYZ_Backup_2.0.0.0-417_2022_08_14_12_10.gz"

我发现引号通常很有用,但要删除",请使用--raw-output.

答案2

与您一起走的规范方式,就是使用,但在这里,jqwill 失败并出现错误:

parse error: Expected another array element at line 6, column 5

我有另一种方法使用:

#!/bin/bash

node<<EOF
let json = $(< file.json)
console.log(json["backupFiles"][0])
EOF

或者简单地:

node -pe 'JSON.parse(process.argv[1]).backupFiles[0]' "$(cat file.json)"

如果JSON结构良好。

输出:

XYZ_Backup_2.0.0.0-417_2022_08_14_12_10.gz    

相关内容