【问题标题】:JSON Array string getting split at space for every value using jq使用 jq 为每个值在空间上拆分 JSON 数组字符串
【发布时间】:2021-06-02 10:32:31
【问题描述】:

我正在尝试使用 jq 从 json 文件中读取命令。 虽然我能够根据要求读取内容,但目前面临的唯一问题是,在从 json 数组获取值后,每个字符串值都会自动拆分一个空间,该空间将字符串的内容划分为 n 个值而不是一个。

JSON 文件

{
"baseVersion": "abc",
"patches": [{
    "version": "122",
    "description": "This patch contains fixes blah blah blah ",
    "iBuild": "60",
    "files": [{
        "fullPath": "20.6.I60.jar",
        "nodeTypes": [
            "a",
            "b"
        ],
        "productTypes": ["a", "b"],
        "restart": "true",
        "service_commands": [{
            "node_name": ["a"],
            "command": ["ls","date","demo"]
        },{
            "node_name": ["b"],
            "command": ["singleline command00"]
        }]
    }]
}]} 

读取内容的代码

#!/bin/bash
trap 'Exit 1' INT TERM
umask 022


getServiceRestartForNode()
{
  local patchConfFile="/pathto/patch_conf.json"

  local query='.patches[] | .version as $v'
  query+=' | .files[] | .service_commands[] |.command[]'

  local outputCommands=($(jq -cr "$query" "$patchConfFile"))

  local result=${PIPESTATUS[0]}

  if [ "$result" -ne 0 ]
  then
    Display -e "ERROR: Error listing files (error code: '$result')"
    return 1
  else

  echo "${outputCommands[@]}"
    for servicecommand in "${outputCommands[@]}"
      do
        "$servicecommand"
    # if [[ "$?" -ne 0 ]]
    # then
    #   display "0" "command $servicecommand failed."
    # fi
      done
  fi
  return 0
}

if  [[ $1 = "-o" ]]; then
    echo "Option -o turned on"
    getServiceRestartForNode
else
    echo "You did not use option -o"
fi 

电流输出

Option -o turned on
ls date demo singleline command
a.out  demo.sh  patch_conf.json
Wed Jun  2 16:29:23 IST 2021
demo.sh: line 26: demo: command not found
demo.sh: line 26: singleline : command not found

预期输出

Option -o turned on
ls date demo singleline command00
a.out  demo.sh  patch_conf.json
Wed Jun  2 16:29:23 IST 2021
demo.sh: line 26: demo : command not found
demo.sh: line 26: singleline command00 : command not found

最后执行的“单行”,但应该是“单行命令”。

提前谢谢你

【问题讨论】:

  • 引用所有的 shell 变量/数组扩展
  • @Inian 完成,请立即查看。

标签: arrays json shell jq


【解决方案1】:

替换这些行:

  local outputCommands=($(jq -cr "$query" "$patchConfFile"))

  local result=${PIPESTATUS[0]}

这些行:

  outputCommands=()
  while IFS='' read -r line || ! result=$line; do outputCommands+=("$line"); done < <(jq -r "$query" "$patchConfFile"; echo -n $?)

你应该很高兴。

在 JQ 命令中,我放弃了 -c 选项,以便结果每行打印一个。然后我使用 BASH 的 read 一次读取一行,用每一行填充数组(从而消除“singleline command00”命令中空间上的单词拆分)。 &lt;(jq ...) 位称为“进程替换”,它允许脚本读取进程的输出,就好像它是一个文件一样。最后, || ! result=$line; echo -n $? 组合在一起,可以在进程替换中进行正确的错误检查。

使用echo 代替实际执行命令,输出如下所示:

</tmp> $ ./so3428.sh -o
Option -o turned on
ls date demo singleline command00
CMD <ls>
CMD <date>
CMD <demo>
CMD <singleline command00>

如果我修改文件名以生成 JQ 错误,我会得到:

</tmp> $ ./so3428.sh -o
Option -o turned on
jq: error: Could not open file x/tmp/so3428.json: No such file or directory
./so3428.sh: line 18: Display: command not found

这里还有更多可以清理的地方,但我会告诉你shellcheck

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多