arrays - jq 输出空字符串时 bash readarray -t 数组赋值的问题

标签 arrays bash indexing jq content-length

首先 - 一个非常简单的代码:

#!/bin/bash

a_string="string"
readarray -t a <<<"$a_string"
echo "${a[@]}"
echo "${#a[@]}"

# read empty string into array
emptystring=""
readarray -t b <<<"$emptystring"
echo "${b[@]}"
echo "${#b[@]}"

# and now - empty array
c=()
echo "${c[@]}"
echo "${#c[@]}"
和输出
string
1

1

0
因此,使用 readarray -t 将空字符串读入 bash 数组显示数组长度为 1。只有真正空数组的长度为 0。
我的问题 - 为什么会发生?
就我而言 - 这是我脚本中的一个片段 - 执行 API 调用,获取 JSON 并应用 jq 过滤器:
URL_list_json=$(curl -s --request GET "$curl_request" --header "Authorization: Bearer ${token}")
readarray -t URL_names <<<"$(echo "$URL_list_json" | jq -r '.[].Body.monitors[].name')"
这是一个 JSON 示例,它从 jq 调用中产生一个空数组:
[
    {
        "Header": {
            "Region": "dc1",
            "Tenant": "tenant1",
            "Stage": "test"
        },
        "Body": {
            "monitors": []
        }
    }
]
这是带有填充内容的 JSON,从 jq 调用返回一个非空数组:
[
    {
        "Header": {
            "Region": "dc2",
            "Tenant": "tenant2",
            "Stage": "qa"
        },
        "Body": {
            "monitors": [
                {
                    "enabled": true,
                    "entityId": "TEST-674BA97E74FC74AA",
                    "name": "production.example.com"
                },
                {
                    "enabled": false,
                    "entityId": "TEST-3E2D23438A973D1E",
                    "name": "test.example.com"
                }
            ]
        }
    }
]

我需要检查是否URL_names数组是否为空。如果不为空,则遍历内容。如果为空 - 意味着 jq 没有返回任何结果 - 白色记录并继续。
如果我使用 if ((${#URL_names[@]}))作为检查数组是否为空的一种方法,即使数组只有一个来自 jq 调用的空字符串,它也会返回 1,因此此逻辑失败。
处理上述案例的替代方法是什么?
我可以将 jq 过滤器的输出分配给一个字符串,然后使用 如果 语句来检查字符串是否为空,如果非空则将字符串分配给数组,但这会引入额外的元素。通过这种方法,我可以完全跳过使用数组——我希望只使用数组来完成这项任务。
谢谢

最佳答案

why it is happening?


因为它读取一行。来自 bash manual here document :

[n]<<< word


[...] The result is supplied as a single string, with a newline appended, to the command on its standard input (or file descriptor n if n is specified).


因为有换行符,readarray读取一个空行。你可以这样做:
readarray -t b < <(printf "%s" "$emptystring")
笔记:
  • echo "$var"不是首选。做 printf "%s" "$var"在 posix shell 中,执行 <<<"$var"在 bash 中时(并且您不关心额外的换行符)。
  • <<<"$(...)"总是看起来很奇怪 - <<<无论如何必须分配一个子shell。做 < <(...) .
  • 你想做:readarray -t URL_names < <(<<<"$URL_list_json" jq -r '.[].Body.monitors[].name')
  • 如果要检查数组是否为空,请检查 jq . I see ex. jq --exit-status '.[].Body.monitors[].name'并检查退出状态。
  • 关于arrays - jq 输出空字符串时 bash readarray -t 数组赋值的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64092857/

    相关文章:

    bash - "<<(command args)"在 shell 中是什么意思?

    Javascript twoSum 算法 : Given an array of integers, 返回两个数字的索引,以便它们加起来达到特定目标

    php - 查找给定值介于数组的哪两个值之间

    php - netstat 和 lsof 的执行问题

    sql - 了解 SQL 中索引的基础知识

    search - 使用 lucene 进行多语言搜索

    python - 使用python的位置索引

    检查c中数组中的值

    Python 3 - 查找出现在多个列表中的字符串,该列表由函数参数填充

    bash - 即使在 chown 和 chmod 之后也无法移动或删除文件