jq:当数组中有任何值时选择

Ber*_*ard 6 json negation any set-intersection jq

给定输入 json

[
  {"title": "first line"},
  {"title": "second line"},
  {"title": "third line"}
]
Run Code Online (Sandbox Code Playgroud)

我们如何仅提取包含在第二个“过滤器”数组中列出的关键字的标题。例如,在此处使用 shell 变量:

filter='["second", "third"]'
Run Code Online (Sandbox Code Playgroud)

在这种情况下的输出将是

[
  {"title": "second line"},
  {"title": "third line"}
]
Run Code Online (Sandbox Code Playgroud)

另外,如何使用数组过滤器来否定。例如:仅返回上一个示例中的“第一行”条目。

有一个类似的回复,但使用的是旧版本的 jq。我希望有一种更直观/可读的方式来使用当前版本的 jq 来做到这一点。

Ini*_*ian 5

您可以结合jq使用数组和 shell 技巧来生成过滤器。首先要生成 shell 数组,请使用 shell 中的数组表示法,如下所示。请注意,以下bash数组符号在其定义中不会用作分隔,符。现在我们需要生成一个正则表达式过滤器来匹配字符串,因此我们生成一个交替运算符

filter=("first" "second")
echo "$(IFS="|"; echo "${filter[*]}"
first|second
Run Code Online (Sandbox Code Playgroud)

您没有提到字符串是否仅在第一个或最后一个匹配,或者可以在该.title部分的任何位置。下面的正则表达式匹配字符串中任意位置的字符串。

现在我们想在 中使用此过滤器jq来匹配.title字符串,如下所示。注意使用 来not否定结果。要提供实际匹配,请删除该部分|not

jq --arg re "$(IFS="|"; echo "${filter[*]}")" '[.[] | select(.title|test($re)|not)]' < json
Run Code Online (Sandbox Code Playgroud)