gpt4 book ai didi

shell - 如何编写委托(delegate)给 jq 的 fish 函数?

转载 作者:行者123 更新时间:2023-12-02 07:19:03 25 4
gpt4 key购买 nike

我正在尝试编写一个名为 jq_select_keys 的 fish 函数,它从给定的 JSON 中选择键的子集。

执行此魔术的 jq 咒语是:

jq -r "with_entries(select([.key] | inside([\"bar\",\"baz\",\"qux\"])))" file.json

现在我正在尝试定义一个名为 jq_select_keys 的方便函数,它将获取我感兴趣的文件名和键,并吐出子集。这是我想出的:

function jq_select_keys --description 'Selects given keys from json input'
set key_names (for key in $argv[2..-1]; echo "\\\"$key\\\""; end)
set key_names_joined (string join "," $key_names)
set jq_args "\"with_entries(select([.key] | inside([$key_names_joined])))\""
echo "Command: jq -r $jq_args $argv[1]"
jq -r $jq_args $argv[1]
end

当我在 fish shell 上运行 jq_select_keys foo.json bar baz qux 时,我得到以下输出:

Command: jq -r "with_entries(select([.key] | inside([\"bar\",\"baz\",\"qux\"])))" foo.json
with_entries(select([.key] | inside(["bar","baz","qux"])))

现在,有趣的一点是我可以复制粘贴 echo 语句的输出,它按预期运行。但是我得到的输出只是我传递给 jq 的查询字符串。

我是 shell 编程的新手,所以我可能搞砸了我的引号。但除此之外,我不知道如何让这个东西工作!

最佳答案

I am new to shell programming, so I might have messed up my quotes.

基本上就是这样。

看来您添加的引号层太多了。

在 fish(以及大多数其他 shell,包括例如 bash 和 zsh)中,引号仅在按字面意义使用时才对 shell 有特殊意义。

这意味着当变量包含 "some string" 时,echo $variable 将打印 "some string" - 这意味着echo 命令接收到带引号的字符串(注意:bash 也会在这里应用分词,所以它实际上会接收到 "somestring",即使您可能认为它被引用了)。

我建议您一个一个地检查您的函数,然后简单地echo 变量。然后想象一下,您将确切的字符串 传递给jq - 它会起作用吗?

例如$key_names 位:

set key_names (for key in $argv[2..-1]; echo "\\\"$key\\\""; end)

这样做的目的显然是转义所有键(从第二个开始的参数)以供 jq 使用。这意味着它们需要被引用一次。它们不需要被第二次引用,因为 shell 不关心非文字引号。

所以任何键都应该看起来像"key"

但是当我们把

printf '%s\n' $key_names

(它将在自己的行上打印每个键)

在这之后,我们看到

\"bar\"
\"baz\"
\"qux\"

那是层的引用!引号本身,以及转义它们的反斜杠。

所以让我们删除一个:

set key_names (for key in $argv[2..-1]; echo "\"$key\""; end)

这将导致 “bar”“baz”“qux”

(这可以通过使用 fish 的 cartesian product 简化为 set key_names\"$argv[2..-1]\")

下一步:

set jq_args "\"with_entries(select([.key] | inside([$key_names_joined])))\""

你在这里的目的是像你一样运行它

jq -r "with_entries(select([.key] | inside([\"bar\",\"baz\",\"qux\"])))" foo.json

在命令行上。但是当您使用变量时,您不需要再次引用其中的字符串 - 所有的拆分和其他扩展都在赋值后发生,并且在替换变量时不会再次发生。

所以简单地删除转义引号

set jq_args "with_entries(select([.key] | inside([$key_names_joined])))"

并且您的功能应该可以正常工作。

结果是:

function jq_select_keys --description 'Selects given keys from json input'
set key_names \"$argv[2..-1]\"
set key_names_joined (string join "," $key_names)
set jq_args "with_entries(select([.key] | inside([$key_names_joined])))"
echo "Command: jq -r $jq_args $argv[1]"
jq -r $jq_args $argv[1]
end

关于shell - 如何编写委托(delegate)给 jq 的 fish 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51080019/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com