【问题标题】:How can I do jq nested for-loops from bash?如何从 bash 执行 jq 嵌套 for 循环?
【发布时间】:2015-12-29 11:21:50
【问题描述】:

我有 52 个 json 文件 (r$i.json),每个文件包含 25 个结果(0 到 24)。我想为每个结果创建一个具有特殊名称的 json 文件。该名称将根据每个结果的内容组成:YYYYMMDDHHMMSS_company_jobtitle.json

生成名称的命令工作正常:

#!bin/bash
for ((j=0;j<=24;j++))
do
   datein=$(jq <"r1.json" ".results[$j].date" | sed 's/"//g')
   dateout=$(date -d "${datein}" +"%Y%m%d%H%M%S")
   company=$(jq <"r1.json" ".results[$j].company" | sed 's/,//g;s/"//g;s/ //g')
   job=$(jq <"r1.json" ".results[$j].jobtitle" | sed 's/,//g;s/"//g;s/ //g')
   jq <"r1.json" ".results[$j]" > ${dateout}_${company}_${job}.json
done

现在,当我用 r$i 替换 r1 并添加 ((i=1;i

r1.json 看起来像这样:

 {

    "radius" : 25,
    "totalResults" : 1329,

    "results" : [

                {
                    "jobtitle" : "job1",
                    "company" : "company1,
                    "date" : "Sun, 01 Sep 2015 07:59:58 GMT",
}
,
                {
                    "jobtitle" : "job2",
                    "company" : "company2",
                    "date" : "Sun, 02 Sep 2015 07:59:58 GMT",
}
,
            |...]
                {
                    "jobtitle" : "job25",
                    "company" : "company25,
                    "date" : "Sun, 25 Sep 2015 07:59:58 GMT",
}

    ]
}

【问题讨论】:

  • 您意识到您可以在一次jq 调用(每个输出文件)中完成所有这些逻辑吗?它是一种强大得多的脚本语言,远比您在这里所称赞的要强大。
  • 另外,“不起作用”——如何不起作用?如果您收到错误消息,请显示确切的错误消息。
  • 感谢@CharlesDuffy 现在它可以工作了。不过,我很想知道更多关于 jq 脚本语言的信息。你有一些好的参考资料可以分享吗?
  • stedolan.github.io/jq/manual 是规范来源。请注意,它允许您使用 + 运算符将字符串连接在一起,因此您可以在 jq 一侧将它们组合成一个,而不是通过单独的调用检索所有这些值然后将它们组合在一起。
  • ...现在,这并不是说它不能全部归结为仅一个 jq 实例生成一个输出流,读取它的 bash 实例可以循环并拆分为多个文件——但一个人必须对此很聪明。我有一些想法,但我想先测试一下。

标签: bash shell for-loop nested jq


【解决方案1】:

您应该尊重fors 中的 bash 语法:

for (( i=0; i&lt;5; i++ ))

((i=1,i&lt; =52,j++)) 不起作用,请使用 ; 代替 ,

【讨论】:

  • 当然,你是对的,谢谢,我编辑了我的帖子。不幸的是,我的问题不是来自那个错误。
  • 尝试拆分您的脚本,使每行的长度少于 70 个字符。避免使用反引号(例如使用$( EXPR ))。还可以尝试定义和使用函数(例如 bash 函数)。通过分解你的问题,你可能会解决它。如果没有,它会让其他人更容易提供帮助。
  • @peak,谢谢你的建议。我分解了脚本并编辑了问题。
【解决方案2】:

1) 你写到你的 i-loop 使用了 ((i=1;i((i-1; i<=52; i++))

2) 我们不能确切地看到你对 r1 和 r$i 做了什么,所以如果 (1) 不能解决你的困难,也许你应该仔细检查你所做的确实是需要的.您应该将“> $outputname”更改为“>> $outputname”吗?

3) 我怀疑与其使用s/"//g,不如使用jq 的-r 选项;您也可以考虑完全避免使用 sed(jq 1.5 具有 sub 和 gsub 功能)。

4) 正如我所说,最好去掉所有的反引号。

【讨论】:

  • 1) 你说得对,我修改了它,谢谢 2) 问题是我无法拥有这样的东西:对于 i=1,为 j=0,j= 2, ..., j=24 for i=2, do for j=0, j=2, ..., j=24 ... for i=52, do for j=0, j=2, . .., j=24 3) 谢谢提示,我会看一下 jq 文档 4) 我刚刚编辑了问题并删除了它们
【解决方案3】:

最后我找到了解决方案,我的问题不是来自 jq,而是来自我用于嵌套循环的语法......这里是:

for ((i=1;i<=kdr;i++))
do
   for ((j=0;j<=24;j++))
   do
    datein=$(jq <"r$i.json" ".results[$j].date" | sed 's/"//g')
    dateout=$(date -d "${datein}" +"%Y%m%d%H%M%S")
    company=$(jq <"r$i.json" ".results[$j].company" | sed 's/,//g;s/"//g;s/ //g')
    job=$(jq <"r$i.json" ".results[$j].jobtitle" | sed 's/,//g;s/"//g;s/ //g')
    jq <"r$i.json" ".results[$j]" > ${dateout}_${company}_${job}.json
   done
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多