【问题标题】:How to find a key-value pair in json text using shell scripting with in-built linux tools like sed?如何使用带有内置 linux 工具(如 sed)的 shell 脚本在 json 文本中查找键值对?
【发布时间】:2019-11-22 00:44:21
【问题描述】:

我有一个 JSON 文件 abc.json 包含文本:

{
    "size": 3,
    "limit": 25,
    "isLastPage": true,
    "values": [

        {
            "slug": "docker_apache_customised",
            "id": 234889,
            "name": "docker_apache_customised",
            "scmId": "git",
            "state": "AVAILABLE",
            "statusMessage": "Available",
            "forkable": true,
            "project": {
                "key": "UFD",
                "id": 36239,
                "name": "UF_docker",
                "public": false,
                "type": "NORMAL",
                "links": {
                    "self": [{
                        "href": "https://rndwww.abc.xxx.net/git/projects/UFD"
                    }]
                }
            },
            "public": false,
            "links": {
                "clone": [{
                    "href": "https://rndwww.abc.xxx.net/git/scm/ufd/docker_apache_customised.git",
                    "name": "http"
                }, {
                    "href": "ssh://git@git.rnd.xxx.net/ufd/docker_apache_customised.git",
                    "name": "ssh"
                }],
                "self": [{
                    "href": "https://rndwww.abc.xxx.net/git/projects/UFD/repos/docker_apache_customised/browse"
                }]
            }
        },

        {
            "slug": "web-software",
            "id": 241533,
            "name": "web-software",
            "scmId": "git",
            "state": "AVAILABLE",
            "statusMessage": "Available",
            "forkable": true,
            "project": {
                "key": "UFD",
                "id": 36239,
                "name": "UF_docker",
                "public": false,
                "type": "NORMAL",
                "links": {
                    "self": [{
                        "href": "https://rndwww.abc.xxx.net/git/projects/UFD"
                    }]
                }
            },
            "public": false,
            "links": {
                "clone": [{
                    "href": "https://rndwww.abc.xxx.net/git/scm/ufd/web-software.git",
                    "name": "http"
                }, {
                    "href": "ssh://git@git.rnd.xxx.net/ufd/web-software.git",
                    "name": "ssh"
                }],
                "self": [{
                    "href": "https://rndwww.abc.xxx.net/git/projects/UFD/repos/web-software/browse"
                }]
            }
        },

        {
            "slug": "web-loy-conf",
            "id": 240959,
            "name": "web-loy-conf",
            "scmId": "git",
            "state": "AVAILABLE",
            "statusMessage": "Available",
            "forkable": true,
            "project": {
                "key": "UFD",
                "id": 36239,
                "name": "UF_docker",
                "public": false,
                "type": "NORMAL",
                "links": {
                    "self": [{
                        "href": "https://rndwww.abc.xxx.net/git/projects/UFD"
                    }]
                }
            },
            "public": false,
            "links": {
                "clone": [{
                    "href": "ssh://git@git.rnd.xxx.net/ufd/web-loy-conf.git",
                    "name": "ssh"
                }, {
                    "href": "https://rndwww.abc.xxx.net/git/scm/ufd/web-loy-conf.git",
                    "name": "http"
                }],
                "self": [{
                    "href": "https://rndwww.abc.xxx.net/git/projects/UFD/repos/web-loy-conf/browse"
                }]
            }
        }
    ],
    "start": 0
}

此文本在 git 项目中包含三个存储库(名为 docker_apache_customisedweb-softwareweb-loy-conf)。可能有更多包含web 作为子字符串的repos。

我想对以web 作为子字符串的存储库执行一些操作,为此我认为我必须在 shell 脚本中应用 for 循环。我不想使用jq 工具

我使用外部工具 jq 编写了一个脚本,但我只想使用 Linux 内置工具来完成。使用jq 的脚本运行良好:

for k in $(jq '.values | keys | .[]' abc.json); do

    value=$(jq -r ".values[$k]" abc.json);
    name=$(jq -r '.name' <<< "$value");

    if [[ $name == *"web"* ]]; then

        #MYLOGIC
    done
done

预期的结果是名称(web-softwareweb-loy-conf)并且能够循环遍历该名称

【问题讨论】:

  • 您需要说明为什么不能使用jq,有什么系统限制或其他原因吗?因为那是工作的正确工具
  • 实际上,实际情况是,我正在运行需要安装 jq 的构建脚本(将通过软件工厂触发),并且 build.sh 脚本应该可以访问它现在我已经从stedolan.github.io/jq/download/linux64/jq 在我的 PC 中安装了 jq,并将其移到了 git repo 中。现在,在我的 bash 脚本中,我正在克隆这个包含“jq”(从互联网下载)的 git 存储库,并从那里运行这个命令“chmod +x jq && sudo cp jq /usr/local/bin”。而且因为我没有管理员权限,所以无法在 /usr/local/bin 中添加 jq
  • 如果我直接从 shell 运行“sudo yum install jq”,我会收到错误:sudo: no tty present and no askpass program specified
  • jq 是适合这项工作的工具。内置工具并非用于处理 JSON 数据,而是用于处理通用数据。任何嵌套的 json 都会因内置工具而失败

标签: json shell sed sh


【解决方案1】:

您可以在 git 存储库中从其当前路径运行 jq,无需将其复制到 PATH 中的目录。添加执行权限后:

value=$(<path to jq in git dir>/jq -r ".values[$k]" abc.json);

你可以使它相对于 git 存储库根目录

value=$(./<path to jq from git repo root>/jq -r ".values[$k]" abc.json);

另外,你可以在变量中设置它的路径

jqbin='./<path to jq from git repo root>/jq'
value=$($jqbin -r ".values[$k]" abc.json);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-08
    • 2013-07-24
    • 1970-01-01
    • 2010-10-20
    • 2015-07-25
    • 1970-01-01
    • 2013-05-08
    • 2014-05-05
    相关资源
    最近更新 更多