【问题标题】:How to extract a json object only using basic commands like sed/awk in shell?如何仅使用 shell 中的 sed/awk 等基本命令提取 json 对象?
【发布时间】:2020-05-31 00:19:49
【问题描述】:

像这样: 我有一个格式如下的 json 文件:

{
    "Item": {
        "summary": {
            "B": "ABCDE"
        },
        "name": {
            "S": "sider"
        },
        "age": {
            "N": "1"
        },
        "data": {
            "B": "abcde"
        }
    }
}

如何仅使用 sed/awk 等现有命令而不在 shell 中安装任何外部工具来获取对象“Item”?

预期输出:

{
    "summary": {
        "B": "ABCDE"
    },
    "name": {
        "S": "sider"
    },
    "age": {
        "N": "1"
    },
    "data": {
        "B": "abcde"
    }
}

【问题讨论】:

  • 不要。您是否尝试仅使用 sedawk 编译 C 代码?您是否尝试仅使用sedawk 操作图像文件?为工作使用正确的工具,并且使用面向行、基于正则表达式的工具不适用于 JSON 等非正则结构化语言。
  • 获得一个合适的工具来处理 JSON;不要让基于 40 年前假设的设计决策决定了您如何使用现代数据。
  • 如果grep '^[[:space:]]' file 不是您所需要的,那么edit 您的问题可以更好地说明您的要求,并且可能还提供更具代表性的示例输入/输出。还添加您迄今为止尝试过的内容。
  • 注意定义get the object "Item" 的含义?您在寻找任何特定的(输出)格式吗?或者也许用您期望看到的输出来更新问题?当我们这样做时,您是否希望所有输入都像您的示例中那样格式化?

标签: json bash shell awk sed


【解决方案1】:

正如 chepner 所建议的,您需要质疑您的限制条件。在某些情况下,你遇到了一手坏牌,不得不处理它。所以这里有一个 sed 方法:

这是一个使用 awk 的修改后的解决方案。 sed 也被抛出以取消缩进:

awk '  
  /^    }/  { p = 0 ; print  }  
  p == 1 { print } 
  /"Item": {/ { print "   {" ; p = 1 }  
'  | sed 's/^   //'

最初发布了这个(但注意到输出与您的期望不符):

sed -n '/^    "Item": {/,/^    }/p'

上面的 sed 方法假设 Item 是缩进的,就像您在上面的示例输入中一样。

这是使用我最喜欢的 jq 的方法:

jq '.Item'

你最好检查一下你的机器上是否安装了带有 json 包的 python。这是一个满足您需求的 python3 脚本:

#!/usr/bin/env python3

import json
import sys
j = json.load( sys.stdin ) 
print(json.dumps(j["Item"]))

【讨论】:

  • 谢谢@Mark,这几乎就是我想要的,除了一个区别:在你的第一个答案中 awk&sed 之后,我在输出 json 中有一些额外的空格。
  • awk ' /^ }/ { p = 0 ; print } p == 1 { print } /"Item": {/ { print "{" ; p = 1 } ' | sed 's/^ //'这样更合适吗?
  • 我更喜欢 awk/sed 答案而不是 sed 答案,因为它更正确 - “项目”标签印有 sed 唯一答案。只要您收到格式良好的输入,它就应该继续为您工作。最终,这不是一个通用的解决方案,因为许多输入会破坏它。
【解决方案2】:

这是你需要的:

sed -n '/^    "Item": {/,/^    }/{s/"Item": //;s/^    //;p}'

它基本上建立在Mark's solution 的基础上,通过两次替换来删除"Item": 并在printing 之前取消缩进4 个空格。

【讨论】:

    【解决方案3】:

    习惯上,使用sed/awk 之类的行感知工具来操作JSON 之类的嵌套数据格式是不正确的。但是,如果您的选择有限,那么最好的方法如下:

    1. 将多行文件转换为单行
    2. 使用awk/sed 提取您的Item

    这是一个基于sed 的解决方案:

    bash $ <file.json tr '\n' ' ' | sed -E 's/^ *{ *"Item": +//; s/ *}$//'
    

    【讨论】:

    • 谢谢@Dmitry,但我在输出中得到了sed: -e expression #1, char 18: Invalid preceding regular expression
    • 你必须在linux上——我的解决方案对MacOS很好。那么对于 linux,您需要引用左大括号,如下所示:&lt;file.json tr '\n' ' ' | sed -E 's/^ *\{ *"Item": +//' | sed -E 's/ *}$//'
    猜你喜欢
    • 2022-01-13
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2014-10-19
    • 2020-09-26
    相关资源
    最近更新 更多