【问题标题】:Problem printing array with spaces using bash使用 bash 打印带有空格的数组时出现问题
【发布时间】:2021-08-23 05:03:26
【问题描述】:

我正在尝试在 bash 中从 json 打印数组数据,为此我使用 jq。问题是,如果记录的值包含空格,它会弄乱输出。下面是演示这个问题的 bash 脚本:

这是完整的源代码(需要jq):

#!/bin/bash

# 1) Declare a sample json with 3 records:

json_data=$(cat <<EOF
{
   "records":[
      {
         "name":"record1",
         "value":"\"1.this-is-string-value-of-record-1-with-no-spaces\""
      },
      {
         "name":"record2",
         "value":"\"2. this is string value of record 2 with spaces\""
      },

      {
         "name":"record3",
         "value":"\"3. this is string value of record 3 with spaces\""
      }
   ]
}
EOF
)

# 2) create the first list of array from .name

record=($(echo "${json_data}" | jq -r ".records[].name" | tr '\n' ' '))


# 3) create the second list of array from .value

 record2=($(echo "${json_data}" | jq -r ".records[].value" | tr '\n' ' '))

# 4) printout the array

for i in "${!record[@]}"; do

 echo "The record [ ${record[i]} ] belongs to [ ${record2[i]} ]"

done

输出:

The record [ record1 ] belongs to [ "1.this-is-string-value-of-record-1-with-no-spaces" ]
The record [ record2 ] belongs to [ "2. ]
The record [ record3 ] belongs to [ this ]

预期输出:

The record [ record1 ] belongs to [ 1.this-is-string-value-of-record-1-with-no-spaces ]
The record [ record2 ] belongs to [ 2. this is string value of record 2 with spaces ]
The record [ record3 ] belongs to [ 3. this is string value of record 3 with spaces ]

您能解释一下为什么它不接受空格值吗?谢谢。

【问题讨论】:

  • 因为$(echo ...)经历了字段拆分。
  • 你的意思是数组声明有字段分割?如何让它接受多个数组。也许没有像我在那里那样创建空间tr '\n' ' ' 的替代方法。
  • 是的。使用内置的readarray 填充数组对您来说会容易得多。试一试。
  • @KalibZen 数组声明并不特殊;如果没有双引号,$(somecommand) 的结果将被拆分为“单词”(不是行或记录或类似的任何有用的东西),然后任何看起来像文件名通配符的东西都将扩展为匹配项的列表.这几乎不是你想要的。如果你双引号它,它根本不会分裂。这样做的正确方法是让jq 输出以null 分隔的项目,并使用readarray -d '' -t 来读取它们。请参阅 chepner 的回答 here
  • 为什么是-d ' '?你想用换行符分割输入,readarray -t record2 ... 就足够了。

标签: bash jq


【解决方案1】:

readarray 工作(来自 bash):

# 2) create the first list of array from .name
readarray -t record < <(echo "${json_data}" | jq -r ".records[].name")

# 3) create the second list of array from .value
readarray -t record2 < <(echo "${json_data}" | jq -r ".records[].value")

# 4) printout the array
for i in "${!record[@]}"; do
    # for removing double quotes
    record2[i]="${record2[i]#\"}"
    record2[i]="${record2[i]%\"}"
    echo "The record [ ${record[i]} ] belongs to [ ${record2[i]} ]"
done

输出:

The record [ record1 ] belongs to [ 1.this-is-string-value-of-record-1-with-no-spaces ]
The record [ record2 ] belongs to [ 2. this is string value of record 2 with spaces ]
The record [ record3 ] belongs to [ 3. this is string value of record 3 with spaces ]

备注:

  • readarray 在行上工作(jq 的输出也是)。所以,不要使用-d 选项
  • 使用 -t 选项删除 EOL 分隔符 ('\n')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-22
    • 2022-11-26
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    相关资源
    最近更新 更多