【问题标题】:Bash Shell script extract Json objectBash Shell 脚本提取 Json 对象
【发布时间】:2014-03-02 06:26:38
【问题描述】:

在 Bash shell 脚本中,我想提取一个对象。例如,使用以下 json 文件,我想提取 dependencies 对象,它应该以任何格式返回我:"dmg": ">= 0.0.0", "build-essential": ">= 0.0.0", "windows": ">= 0.0.0",你是如何做到的?

//我的数据1.json:

{
    "platforms": {
        "amazon": ">= 0.0.0",
        "arch": ">= 0.0.0",
        "centos": ">= 0.0.0",
        "debian": ">= 0.0.0"
    },
    "dependencies": {
        "dmg": ">= 0.0.0",
        "build-essential": ">= 0.0.0",
        "windows": ">= 0.0.0"
    },
    "recommendations": {}
}

//我的数据2.json:

{
    "platforms": {
        "amazon": ">= 0.0.0",
        "arch": ">= 0.0.0",
        "centos": ">= 0.0.0",
        "debian": ">= 0.0.0"
    },
    "recommendations": {},
    "dependencies": {
        "dmg": ">= 0.0.0",
        "build-essential": ">= 0.0.0",
        "windows": ">= 0.0.0"
    }
}

//我的数据3.json:

{
    "dependencies": {
        "dmg": ">= 0.0.0",
        "build-essential": ">= 0.0.0",
        "windows": ">= 0.0.0"
    },
    "platforms": {
        "amazon": ">= 0.0.0",
        "arch": ">= 0.0.0",
        "centos": ">= 0.0.0",
        "debian": ">= 0.0.0"
    },
    "recommendations": {}
}

//我的数据4.json:

{
    "dependencies": {
        "dmg": ">= 0.0.0",
        "build-essential": ">= 0.0.0",
        "windows": ">= 0.0.0"
    }
}

//我的数据5.json(压缩):

{"dependencies":{"dmg":">= 0.0.0","build-essential":">= 0.0.0","windows":">= 0.0.0"},"platforms":{"amazon":">= 0.0.0","arch":">= 0.0.0","centos":">= 0.0.0","debian":">= 0.0.0"},"recommendations":{}}

【问题讨论】:

    标签: json bash shell awk grep


    【解决方案1】:

    这是awk的一种方式:

    awk -v RS= -F'},|{' '{print $5}' file | awk 'NF'
    

    $ awk -v RS= -F'},|{' '{print $5}' f | awk 'NF'
        "dmg": ">= 0.0.0",
        "build-essential": ">= 0.0.0",
        "windows": ">= 0.0.0"
    

    【讨论】:

    • 我很好奇,它怎么知道要提取的名为“dependencies”的块?我在您的命令中没有看到关键字“依赖项”。
    • @NamNguyen 我将输入设置为段落模式RS=,将字段分隔符设置为},{。文件拆分后,我只需通过声明$5 来选择您要查找的字段。那是您需要的字段持有值。最后一个管道是删除空行。
    • 这非常好,我很难理解您的解决方案。我仍在阅读您的推荐并向专业人士学习:)。 Kinna 喜欢你的解决方案 :)
    • @NamNguyen 谢谢:)。这很简单。只需查看您的输入并通过在每个 },{ 处拆分它们来计算字段。你会看到你的块是5th 字段。
    【解决方案2】:
    sed -n '/dependencies/, /}/ p' t|grep '>='
    


    这是如何工作的:

    首先获取dependencies块之间的文本,然后提取依赖关系。

    请注意,此方法与依赖块所在的文本中的 where 无关。 只要它存在,你就会得到答案。


    aman@apollo:~$ sed -n '/dependencies/, /\}/ p' t|grep '>='
            "dmg": ">= 0.0.0",
            "build-essential": ">= 0.0.0",
            "windows": ">= 0.0.0"
    

    使用sed -n '/dependencies/, /}/ p' t|grep '.*='

    如果依赖块中可以有~== 之类的符号(而不仅仅是>=)。


    压缩版 对于压缩版本,您可以先“解压缩”(插入换行符)文件,然后应用相同的转换。
    sed -e 's/:{/:{\n/g'  -e  's/},/\n},\n/g' d5|sed -n '/dependencies/, /}/ p'|grep '>='
    

    原始解决方案适用于所有其他 4 个文件。

    【讨论】:

    【解决方案3】:
    $ $ tr -d '\n' < myjson.json | sed -e's/[}{]//g' | sed -e's/.*dependencies\":\(.*\)\s*,.*/\1/g' | sed -e's/^ *//g' | sed -e's/, */, /g'
    "dmg": ">= 0.0.0", "build-essential": ">= 0.0.0", "windows": ">= 0.0.0"
    

    【讨论】:

    • 看起来这个解决方案不适用于我的某些情况。
    • 对不起,我不知道你的情况:)
    • 例如,我的情况是json文件被压缩,比如all in a line。但我仍然感谢您的意见。
    • tr -d '\n' &lt; myjson.json 就是这样做的。
    • 例如,这个测试用例会失败: { "b": { }, "dependencies": { "dmg": ">= 0.0.0", "build-essential": ">= 0.0.0", "windows": ">= 0.0.0" }, "a": { } }
    【解决方案4】:

    你看过jsawk吗?我通常会使用 python 在 UNIX 系统上解析 JSON 数据,因为它通常与操作系统捆绑在一起。

    不管怎样,你可以试试这个:

    awk "/dependencies/,/}/ { print }" test.json | grep ":" | grep -v dependencies
    

    一般来说,获取两个模式/字符串之间的文本:

    awk "/Pattern1/,/Pattern2/ { print }" inputFile
    

    然后使用grep“:”获取对象中所有包含':'的行,然后通过获取后续所有不包含对象名的行来过滤掉对象名本身

    更新: 对于json格式不漂亮

    sed "s/[,{}]/&\n/g" prettified.json | awk "/dependencies/,/}/ { print }" | grep ":" | grep -v dependencies | awk '{$1=$1}1'
    

    【讨论】:

    • 如果 json 文件不是很漂亮的格式,这可能是一个问题,例如 json 文件被压缩成一行。有什么想法吗?
    • 更新了正则表达式,现在应该适用于漂亮和丑陋的格式lol
    猜你喜欢
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 2022-08-14
    • 1970-01-01
    • 2014-08-25
    相关资源
    最近更新 更多