为jq数组中的每个项运行一个命令

Asd*_*dfg 6 bash jq

这是我的输入文件的样子:

[
  {
    "ConfigType": "ABC",
    "Prop1": 3,
    "Prop2": 30
  },
  {
    "ConfigType": "XYZ",
    "Prop3": "Hello",
    "Prop4": "World",
    "Prop5": "Application"
  }
]
Run Code Online (Sandbox Code Playgroud)

我需要为每个项目准备插入语句.

这就是我的jq命令的样子,它给了我每个项目.

cat app-cnfg.json |  jq -r ".[]"
Run Code Online (Sandbox Code Playgroud)

我该如何执行aws dynamodb put-item --table-name "xxx" --item <<array's element>>

Ben*_* W. 7

您可以通过管道传输到xargs

jq -c '.[]' app-cnfg.json \
    | xargs -L 1 aws dynamodb put-item --table-name "xxx" --item
Run Code Online (Sandbox Code Playgroud)

-cjq 的选项可确保每个元素都在一行上,并且-L 1选项xargs可确保每个项目被调用一次。

如果您想避免尾随空格的潜在问题(将以args下行视为当前行的延续),则可以使对象零字节分隔:

jq -j '.[] | tostring + "\u0000"' app-cnfg.json \
    | xargs -0 -n1 aws dynamodb put-item --table-name "xxx" --item
Run Code Online (Sandbox Code Playgroud)

-j选项禁止jq的换行符,tostring对对象进行字符串化并+ "\u0000"附加一个零字节。

xargs -0 -n1 期望零字节定界输入,并对每个参数运行一次命令。

  • 您可以; 这有点棘手。参见https://github.com/stedolan/jq/issues/1271进行讨论-`-j'禁止换行符,因此您可以通过表达式添加NUL。`jq -j'。[] | (。+“ \ u0000”)'`进行汇总(如果谨慎的话,可以从数据中过滤掉它们)。 (4认同)

Ini*_*ian 5

您可以应用过滤器来提取JSON数组的每个元素并将其提供给数组,bash然后再迭代其内容.假设你有bash4.0或更高,你可以使用mapfile命令

mapfile -t configArr < <(jq -c '.[]'  < app-cnfg.json)
Run Code Online (Sandbox Code Playgroud)

现在我们遍历数组,为每个配置项运行命令,

for config in "${configArr[@]}"; do
    aws dynamodb put-item --table-name "xxx" --item "$config"
done
Run Code Online (Sandbox Code Playgroud)

(或)使用更有效的方法使用while循环和read命令从输入数据流中读取(适用于bash不支持的版本mapfilereadarray)

while IFS= read -r config; do
    aws dynamodb put-item --table-name "xxx" --item "$config"
done< <(jq -c '.[]' < app-cnfg.json)
Run Code Online (Sandbox Code Playgroud)