给出输入json
[
{"title": "first line"},
{"title": "second line"},
{"title": "third line"}
]
我们如何仅提取包含第二个“过滤器”数组中列出的关键字的标题。例如,在此处使用shell变量:
filter='["second", "third"]'
在这种情况下的输出将是
[
{"title": "second line"},
{"title": "third line"}
]
此外,如何使用数组过滤器取反。 例如:仅返回上一个示例中的“第一行”条目。
有一个similar reply,但使用的是旧版的jq。 我希望对当前版本的jq有一种更直观/更易理解的方法。
答案 0 :(得分:2)
您可以结合使用jq
和shell技巧(使用数组)来生成过滤器。首先要生成shell数组,请使用如下所示的shell数组表示法。请注意,以下bash
数组的表示法将 not 以,
作为其定义的分隔符。现在我们需要产生一个正则表达式过滤器来匹配字符串,因此我们产生一个交替运算符
filter=("first" "second")
echo "$(IFS="|"; echo "${filter[*]}"
first|second
您没有提到字符串仅在第一个或最后一个匹配,还是可以在.title
部分中的任何位置。下面的正则表达式匹配字符串中任何位置的字符串。
现在,我们要在jq
中使用此过滤器,以与.title
字符串进行匹配,如下所示。注意,使用not
来否定结果。要提供实际匹配,请删除部分|not
。
jq --arg re "$(IFS="|"; echo "${filter[*]}")" '[.[] | select(.title|test($re)|not)]' < json
答案 1 :(得分:0)
解决涉及“ any”一词的问题的一种方法通常是使用jq的private void runCommand(){
String pathToScript = getDir("my_scripts",Context.MODE_PRIVATE).getAbsolutePath() + File.separator + "test.sh";
String[] commands = {"bash", "-c", pathToScript};
try{
java.lang.Process process = new ProcessBuilder()
.command(commands)
.directory(new File (getDir("my_scripts",Context.MODE_PRIVATE).getAbsolutePath()))
.redirectErrorStream(true)
.start();
//Read output
StringBuilder output = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = bufferedReader.readLine()) != null){
output.append(line + "\n");
}
if (process.waitFor() == 0){
Log.i(TAG, "Success");
} else{
e.printStackTrace();
}
}catch(IOException e){
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
,例如使用您的shell变量:
any
与形式逻辑一样,您可以使用jq --argjson filter "$filter" '
map((.title | split(" ")) as $title
| select(any( $title[] as $t
| $filter[] as $kw
| $kw == $t )))' input.json
或all
(与否定结合使用)来解决否定的问题。但是请不要忘记,如果您使用any
,
jq的not
是一个零度数过滤器。
not
上面使用的是“关键字匹配”,因为这是问题所指定的内容,但是当然上述jq表达式可以轻松地修改为使用正则表达式或其他某种类型的匹配。
如果关键字列表很长,那么毫无疑问希望有一个更好的数组交集算法。