【问题标题】:Build a Json in Bash with two arrays用两个数组在 Bash 中构建一个 Json
【发布时间】:2020-06-23 12:27:03
【问题描述】:

我实际上在 bash 中有 2 个包含字符串值的数组。 类似的东西:

Array1=(Kevin Paul)
Array2=(OK DANGER)

我想创建一个具有 2 个属性的 json,如果可能的话,类似的东西

{
   "results":[
      {
         "nom":"Kevin",
         "status":"OK"
      },
      {
         "nom":"Paul",
         "status":"Danger"
      }
   ]
}

我读了很多关于 JQ 的文章,我已经将它们用于我的数组,但没有人谈论我想要的东西 :(

我的一个测试(没有回应我想要的):

declare -a test_array
declare -a test_array2
test_array=(apple orange lemon)
test_array2=(DANGER OK WARNING)
echo ${test_array[0]}

echo '['
printf '{"CVEC": "%s", "LVL" : "%s"},\n' "${test_array[@]}, ${test_array2[@]}" | sed '$s/,$//'
echo ']'

Display 

[
{"CVEC": "apple", "LVL" : "orange"},
{"CVEC": "lemon, DANGER", "LVL" : "OK"},
{"CVEC": "WARNING", "LVL" : ""}
]

【问题讨论】:

  • 使用jq 的原因是,无论什么值存储在数组中,它都能确保有效的JSON。纯粹的bash 方法要求您对值进行所有检查,以确保正确处理需要转义的内容。
  • 是的,但是我没有找到任何响应此问题的 bash 和 json 构建:(
  • 那是因为bash 没有内置的方法来安全地处理生成的 JSON。
  • 看来您正在寻找 zip 功能。例如。 github.com/stedolan/jq/issues/609
  • 不,完全不是我需要的

标签: arrays json bash jq


【解决方案1】:

使用模板引擎perlTemplate::Toolkit命令行工具:tpage

文件

标题:

{
   "results":[

页脚:

   ]
}

file.tpl(模板):

    {
        "nom": "[% x1 %]",
        "status": "[% x2 %]"
    }[% sep %]

Bash 脚本

#!/bin/bash

arr1=( Kevin Paul  )
arr2=( OK danger )

{
    cat header
    for i in "${!arr1[@]}"; do
        ((i==${#arr1[@]}-1)) && sep='' || sep=','
        tpage --define x1="${arr1[i]}" \
              --define x2="${arr2[i]}" \
              --define sep=$sep file.tpl
    done
    cat footer
} | tee file.json

验证

$ jq . file.json
{
  "results": [
    {
      "nom": "Kevin",
      "status": "OK"
    },
    {
      "nom": "Paul",
      "status": "danger"
    }
  ]
}

对于 debian 和 debian 之类的:

apt install libtemplate-perl

通过 CPAN:

cpan -i Template::Toolkit

查看http://www.template-toolkit.org/docs/tools/tpage.html

【讨论】:

    【解决方案2】:

    一种方式:

    paste <(printf "%s\n" "${Array1[@]}") <(printf "%s\n" "${Array2[@]}") |
        jq -nRc '{ results: [inputs] | map(split("\t") | { nom: .[0], status: .[1] }) }'
    

    生产

    {"results":[{"nom":"Kevin","status":"OK"},{"nom":"Paul","status":"DANGER"}]}
    

    这假定您的数组元素中没有制表符或换行符。它使用paste 生成对应的数组元素对,由制表符分隔,每行一对,然后使用jq 从中创建 JSON 输出。

    【讨论】:

      【解决方案3】:

      如果目标是坚持使用非jq 解决方案 - 并且 chepner 的 cmets 关于需要验证数组条目对于 这种 情况来说不是问题 - 一个想法是循环数组索引。

      测试数据:

      $ declare -a test_array=(apple orange lemon)
      $ typeset -p test_array
      declare -a test_array=([0]="apple" [1]="orange" [2]="lemon")
      
      $ declare -a test_array2=(DANGER OK WARNING)
      $ typeset -p test_array2
      declare -a test_array2=([0]="DANGER" [1]="OK" [2]="WARNING")
      

      通过索引 (0,1,2) 的简单循环:

      sfx=','                                                   # default printf suffix is a comma
      
      for (( i=0 ; i<${#test_array[@]} ; i++ ))
      do
          (( ${i} == ( ${#test_array[@]} - 1 ) )) && sfx=''     # clear suffix for last pass through loop
      
          printf '{"CVEC": "%s", "LVL" : "%s"}%s\n' "${test_array[${i}]}" "${test_array2[${i}]}" "${sfx}"
      done
      

      生成以下内容:

      {"CVEC": "apple", "LVL" : "DANGER"},
      {"CVEC": "orange", "LVL" : "OK"},
      {"CVEC": "lemon", "LVL" : "WARNING"}
      

      【讨论】:

        猜你喜欢
        • 2023-02-23
        • 1970-01-01
        • 2021-04-14
        • 1970-01-01
        • 2021-12-12
        • 2010-12-31
        • 2018-01-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多