【问题标题】:jq selection of an attribute value based on another attribute's length and store that value in a text filejq 根据另一个属性的长度选择属性值并将该值存储在文本文件中
【发布时间】:2021-07-02 19:17:31
【问题描述】:

我正在使用 jq 并希望根据另一个数组不为空的条件从大型 json 文件中选择属性的值。如果那是空的,那么我们应该忽略该值并检查下一个属性,依此类推。我们还希望将所有满足非空数组条件的值存储到一个文本文件中,每行一个值且不加引号。

例如,我有一个大型 json 文件(16+ GB),其中包含 200k 以及以下条目:

{"one": "Some string", "two": "A", "three": []}
{"one": "Some string", "two": "B", "three": [{"a": 1,"b": 2}]}
{"one": "Some string", "two": "C", "three": []}

具体来说,我想选择只有那些 "two" 属性的值,其中数组"three" 的值不为空。因此,在上面的示例中,应该只返回值 "B",而应该忽略所有其他值。我还需要将返回的所有此类值(如上述情况中的 "B" )存储到一个文本文件中,每行一个且不加引号。

似乎无法弄清楚该怎么做。非常感谢您的帮助。

【问题讨论】:

  • 您显示的输入无效(对象必须是键/值对);什么是预期的输出? two的值,每行一个?引用,未引用?
  • 这是一个大型 json 文件,其中包含我在问题中所述格式的对象。我希望属性 2 的每个值每行一个,并且仅在属性 3 不为空的情况下不加引号。
  • 1.请注意,null 是一个 JSON 值,与 [] 不同,因此您尝试的澄清只会使水变得混乱。 2. 请给出一个更全面的例子,包括预期的输出,如果可能的话,如果“B”值出现不止一次,则显示预期的结果。
  • 很抱歉我对 JSON 格式缺乏了解。是的,当属性“三”中有一些值时,我想要属性“二”中的所有值。

标签: arrays json conditional-statements jq


【解决方案1】:

很遗憾,最初在 Q 中显示的输入不是有效的 JSON,因此如果要以直接方式使用 jq,则必须进行一些更改或更正。

假设已经进行了这些更改,以下说明了一种避免“破坏”输入的有效方法:

调用:jq -rnf program.jq input.json

[inputs | select(.three != []) | .two] | unique[]

这会产生不同的值,排序。

另一种选择

上述解决方案涉及将所有相关的 .two 值收集到一个数组中。如果不满意, 一种替代方法是将相关 .two 值的流通过管道传输到sort

< input.json jq -rn 'inputs | select(.three != []) | .two' | sort -u > two.txt

【讨论】:

  • @MuhammadShakeel - 如果您可以通过提供有效的 JSON 并阐明您的要求来解决您的问题,这将有所帮助。也请使用适当的词汇,例如如果“空”是指一个空数组,那么请说出来。
  • 好。我对 Q 投了赞成票,相信您会发现这个答案不仅有效,而且符合您的要求,或者至少提供了足够的指导。
  • @MuhammadShakeel 这两种解决方案都适用于您的示例输入:onetwo。因此,如果您看到不同的东西,您必须提供与您的真实输入相对应的示例输入。
【解决方案2】:

如果输入文件很大,您应该一个接一个地处理元素,而不是使用--slurp 一次将它们读入一个数组并一起处理它们。否则可能会出现内存问题。

修正输入

{"one": "Some string", "two": "A", "three": []}
{"one": "Some string", "two": "B", "three": [{"a": 1},{"b": 2}]}
{"one": "Some string", "two": "C", "three": []}

命令

jq -r 'select(.three | length &gt; 0) | .two' &lt; file_in.json &gt; file_out.json

输出

B 

【讨论】:

  • @Muhammad:输入来自file_in.json,并存储在file_out.json
  • @Muhammad:要使命令生效,您必须将输入数据保存到file_in.json。如果您在控制台上看到输出(没有重定向到file_out.json),您可能没有权限将数据保存到file_out.json
  • ok ... 那么如果文件重定向由于某种原因在您的机器上不起作用,这里是您使用 echo 的示例:echo '{"one": "Some string", "two": "A", "three": []}{"one": "Some string", "two": "B", "three": [{"a": 1},{"b": 2}]}{"one": "Some string", "two": "C", "three": []}' | jq -r 'select(.three | length &gt; 0) | .two'
【解决方案3】:

你可以这样做(见playground):

jq --raw-output 'if (.three | length > 0) then .two else empty end'

并将输出重定向到文件:

jq --raw-output 'if (.three | length > 0) then .two else empty end' > outfile

这假定输入有效,因此操场示例使用字符串数组。

【讨论】:

  • 没有 slurping 的答案会产生错误:jq: error (at :2): Cannot index array with string "three" exit status 5
  • @MuhammadShakeel 你删除了--slurp 吗?如果您不删除它,您会看到该错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-29
相关资源
最近更新 更多