【问题标题】:How to pass jq values from master shell script to child shell script如何将 jq 值从主 shell 脚本传递到子 shell 脚本
【发布时间】:2021-09-20 20:39:08
【问题描述】:

在一个 shell 脚本(比如master_script.sh)中,我尝试使用jq 解析 json 文件(country.json)并将这些值传递给另一个 shell 脚本(child_script.sh),然后打印来自 @ 987654327@,因为我将在那里使用它。

ma​​ster_script.sh

#!/bin/bash
$(jq -r ' .countries[] | .country as $cntry | .city[] | (.) as $ct |
"child_script.sh $cntry $ct"' country.json)

country.json

 {
        "countries": [
            {"country":"India","city":["India1","India2","India3"]},
            {"country":"USA","city":["USA1","USA2","USA3"]}
           
           ]
    }

child_script.sh

#!/bin/bash
country=$1
city=$2
echo "country: $country, city: $city"\n
# I need to use these two variables for further calculation

child_script.sh 的所需输出应类似于:jqplay

country: India, city: India1
country: India, city: India2
country: India, city: India3
country: USA, city: USA1
country: USA, city: USA2
country: USA, city: USA3

但我无法做到这一点。

【问题讨论】:

  • 请注意,使用命令替换来生成 shell 命令通常不会像您期望的那样工作 - 请参阅 BashFAQ #50。 (如果它确实按您预期的方式工作,那将无法在 shell 语言中处理不受信任的数据,所以它不这样做是一件非常好的事情。

标签: arrays json bash shell jq


【解决方案1】:

由于某些国家/地区(例如“新西兰”)的名称中有空格,您可能需要考虑到这一点,例如如下:

jq -r '.countries[]
       | .country as $country
       | .city[] | "\($country)\t\(.)"' | 
  while IFS=$'\t' read -r country city; do
     ./child_script.sh "$country" "$city"
  done

【讨论】:

  • 使用 NUL 分隔符而不是制表符更安全。 (当我感觉特别偏执时,我让 jq 在打印之前删除数据中的所有 NUL,然后显式添加分隔的)。
【解决方案2】:

while read 是通用方法,但我们可以利用xargs,因为循环体由执行程序组成。

jq -r '
   .countries[] |
   .country as $country |
   .city[] |
   @sh "\($country) \(.)"
' country.json |
xargs -rl ./child_script.sh

【讨论】:

  • xargs unquoting 与 POSIX sh 解析相当兼容。我希望仔细分析jq 发出的子集在信任之前全部由 xargs 处理。
  • 不支持-r的xargs版本怎么办? (参见例如stackoverflow.com/questions/8803987/…
  • @Charles Duffy,它只需要处理 jq 产生的东西,它确实可以。
  • @peak 我认为不可能有一个通用的解决方案,至少不会让事情变得非常复杂。这将涵盖很多人。它将适用于所有 GNU 系统,然后是一些系统。其余部分必须根据需要进行调整。
【解决方案3】:

我认为您正在寻找类似的东西:

#!/bin/bash
jq -r '.countries[] | .country + " " + .city[]' country.json | while read r; do
    ./child_script.sh "$r"
done

您需要循环使用从jq 命令获得的结果,并为每一行应用脚本。

注意:删除child_script.shecho命令后的\n

【讨论】:

  • 这行不通,因为它只将一个字符串参数传递给子脚本,它需要两个参数。
猜你喜欢
  • 1970-01-01
  • 2016-10-29
  • 2022-09-27
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-06
  • 1970-01-01
相关资源
最近更新 更多