我正在尝试编写一个名为fish函数的函数jq_select_keys,它从给定的JSON中选择一个键的子集.
jq咒语做这件魔术是:
jq -r "with_entries(select([.key] | inside([\"bar\",\"baz\",\"qux\"])))" file.json
Run Code Online (Sandbox Code Playgroud)
现在我正在尝试定义一个名为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
Run Code Online (Sandbox Code Playgroud)
当我在我的鱼壳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"])))
Run Code Online (Sandbox Code Playgroud)
现在,有趣的是我可以复制粘贴echo语句的输出,并按预期运行.但我得到的输出只是我传递给jq的查询字符串.
我是shell编程的新手,所以我可能搞砸了我的引号.但除此之外,我不知道如何让这件事发挥作用!
我是shell编程的新手,所以我可能搞砸了我的引号.
基本上就是这样.
看来你添加了一层太多的引号.
在鱼(以及大多数其他贝壳,包括例如bash和zsh)中,引号仅在字面上使用时对shell特殊.
这意味着,当一个变量包含"some string",然后echo $variable将打印"some string"-这意味着echo接收到的命令字符串用引号(注:庆典也将适用于此字拆分,因此它实际上会得到"some和string",即使你可能认为它是引用) .
我建议你逐个完成你的功能,只echo需要变量.然后想象你传递,准确的字符串来jq-将它的工作?
比如$key_names:
set key_names (for key in $argv[2..-1]; echo "\\\"$key\\\""; end)
Run Code Online (Sandbox Code Playgroud)
这样做的目的显然是为了逃避所有密钥(从第二个开始的参数)以供使用jq.这意味着他们需要被引用一次.它们不需要再次引用,因为shell不关心非文字引号.
所以任何键都应该是这样的"key".
但是当我们放
printf '%s\n' $key_names
Run Code Online (Sandbox Code Playgroud)
(将在自己的行上打印每个键)
在此之后,我们看到了
\"bar\"
\"baz\"
\"qux\"
Run Code Online (Sandbox Code Playgroud)
这是2个引述的层次!引号本身,以及逃避它们的反斜杠.
所以让我们删除一个:
set key_names($ argv中的键[2 ..- 1]; echo"\"$ key \""; end)
这将导致"bar","baz"和"qux".
(这可以set key_names \"$argv[2..-1]\"通过使用鱼的笛卡尔产品简化 )
现在为下一点:
set jq_args "\"with_entries(select([.key] | inside([$key_names_joined])))\""
Run Code Online (Sandbox Code Playgroud)
你在这里的目的是像你一样运行它
jq -r "with_entries(select([.key] | inside([\"bar\",\"baz\",\"qux\"])))" foo.json
Run Code Online (Sandbox Code Playgroud)
在命令行上.但是当你使用变量时,你不需要再次引用它们中的字符串 - 一旦分配了值,所有的分裂和其他扩展都已经发生,并且当替换变量时不会再发生.
因此,只需删除转义的引号即可
set jq_args "with_entries(select([.key] | inside([$key_names_joined])))"
Run Code Online (Sandbox Code Playgroud)
你的功能应该工作.
结果是:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |