在反向 GREP 之后使用 JQ 解析和 return 适当的 JSON
Parse and return proper JSON with JQ after inverse GREP
我一直在为一些看似简单的事情而苦苦挣扎。
我一整天都在例行公事地使用 iOs 快捷方式来监视我的一台服务器,而快捷方式应用程序在处理 JSON 对象时非常挑剔。
我需要 return 一个格式完美(没有嵌套)的数组;即:
{
{
"term": "alpha"
},
{
"term": "beta"
},
{
"term": "gamma"
},
}
正在从内部 API 调用中获取数据,我需要从现有的术语中过滤出值。
我想知道哪些对象是 return 从 API 编辑的 当前 同名的 运行 tmux。
这是来自 API 调用的未格式化 return :
{
"online_terms": [
{
"term": "alpha"
},
{
"term": "beta"
},
{
"term": "gamma"
}
],
"total": 3,
}
这是目前使用的单线:
list=$(tmux list-sessions -F \#S); curl https://myapi.call| jq -r '.online_terms[] | .term' | grep -v $list
$list 将包含当前 运行 tmux 会话的多行 LS 样式名称。即:
alpha
omega
kappa
这就是我到目前为止一直在使用的,但充其量也很古怪。为了澄清,将我所有的 tmux 会话声明到 $list 变量中,然后执行 API 调用,解析出我需要的嵌套值,对 $list ... 不理想!
而且它只有 returns 单行名称,即(过滤掉 alpha):
beta
gamma
尽管多次尝试将原始数据回输到 JQ 中,但我仍无法将其解析为上述对象类型。
欢迎就如何更干净地反转 grep tmux ls 值或解析为适当的 JSON 对象提出任何建议,谢谢提前寻求任何帮助!
为了展示如何使用 jq 解决问题而无需任何 hackery,让我们首先假设黑名单以某种方式作为文本文件提供,比如 blacklist.txt:
alpha
omega
kappa
然后您可以按照以下行调用 jq:
< blacklist.txt jq --argjson curl "$(curl https://myapi.call)" -Rn '
[inputs] as $blacklist
| [ $curl
| .online_terms[]
| select( .term | IN($blacklist[]) | not) ]'
此处,已使用 --argjson
选项将 curl 命令的输出提供给 jq。
可以轻松修改此解决方案以处理黑名单的其他来源。
另一种选择
您还可以通过 STDIN 将 curl 命令的输出提供给 jq,但是您必须首先将文本黑名单转换为 JSON。这可以通过再次调用 jq 来完成:
curl https://myapi.call |
jq --argjson blacklist "$(jq -Rn '[inputs]' blacklist.txt)" '
[.online_terms[]
| select( .term | IN($blacklist[]) | not)]'
不漂亮,但它强调了一个事实,即如果您的黑名单生成器可以将黑名单提供为 JSON,事情会简单一些。
提供以下解决方案主要是因为它类似于 OP 提出的解决方案,尽管它使用 comm
而不是 grep
,并假设黑名单在文本文件中,blacklist.txt:
curl https://myapi.call |
jq -r '[.online_terms[].term] | sort[]' |
comm -23 - <(sort blacklist.txt) |
jq -Rn '[{term: inputs}]'
这样做的缺点是需要第二次调用 jq 来重建 JSON 实体;它还需要两次排序操作,这可能是不可取的,但如果已经排序,当然可以跳过黑名单的排序。
我一直在为一些看似简单的事情而苦苦挣扎。
我一整天都在例行公事地使用 iOs 快捷方式来监视我的一台服务器,而快捷方式应用程序在处理 JSON 对象时非常挑剔。
我需要 return 一个格式完美(没有嵌套)的数组;即:
{
{
"term": "alpha"
},
{
"term": "beta"
},
{
"term": "gamma"
},
}
正在从内部 API 调用中获取数据,我需要从现有的术语中过滤出值。 我想知道哪些对象是 return 从 API 编辑的 当前 同名的 运行 tmux。
这是来自 API 调用的未格式化 return :
{
"online_terms": [
{
"term": "alpha"
},
{
"term": "beta"
},
{
"term": "gamma"
}
],
"total": 3,
}
这是目前使用的单线:
list=$(tmux list-sessions -F \#S); curl https://myapi.call| jq -r '.online_terms[] | .term' | grep -v $list
$list 将包含当前 运行 tmux 会话的多行 LS 样式名称。即:
alpha
omega
kappa
这就是我到目前为止一直在使用的,但充其量也很古怪。为了澄清,将我所有的 tmux 会话声明到 $list 变量中,然后执行 API 调用,解析出我需要的嵌套值,对 $list ... 不理想!
而且它只有 returns 单行名称,即(过滤掉 alpha):
beta
gamma
尽管多次尝试将原始数据回输到 JQ 中,但我仍无法将其解析为上述对象类型。
欢迎就如何更干净地反转 grep tmux ls 值或解析为适当的 JSON 对象提出任何建议,谢谢提前寻求任何帮助!
为了展示如何使用 jq 解决问题而无需任何 hackery,让我们首先假设黑名单以某种方式作为文本文件提供,比如 blacklist.txt:
alpha
omega
kappa
然后您可以按照以下行调用 jq:
< blacklist.txt jq --argjson curl "$(curl https://myapi.call)" -Rn '
[inputs] as $blacklist
| [ $curl
| .online_terms[]
| select( .term | IN($blacklist[]) | not) ]'
此处,已使用 --argjson
选项将 curl 命令的输出提供给 jq。
可以轻松修改此解决方案以处理黑名单的其他来源。
另一种选择
您还可以通过 STDIN 将 curl 命令的输出提供给 jq,但是您必须首先将文本黑名单转换为 JSON。这可以通过再次调用 jq 来完成:
curl https://myapi.call |
jq --argjson blacklist "$(jq -Rn '[inputs]' blacklist.txt)" '
[.online_terms[]
| select( .term | IN($blacklist[]) | not)]'
不漂亮,但它强调了一个事实,即如果您的黑名单生成器可以将黑名单提供为 JSON,事情会简单一些。
提供以下解决方案主要是因为它类似于 OP 提出的解决方案,尽管它使用 comm
而不是 grep
,并假设黑名单在文本文件中,blacklist.txt:
curl https://myapi.call |
jq -r '[.online_terms[].term] | sort[]' |
comm -23 - <(sort blacklist.txt) |
jq -Rn '[{term: inputs}]'
这样做的缺点是需要第二次调用 jq 来重建 JSON 实体;它还需要两次排序操作,这可能是不可取的,但如果已经排序,当然可以跳过黑名单的排序。