jq和bash:使用--arg的对象构造不起作用
考虑到以下输入:jq和bash:使用--arg的对象构造不起作用,bash,jq,Bash,Jq,考虑到以下输入: J='{"a":1,"b":10,"c":100} {"a":2,"b":20,"c":200} {"a":3,"b":30,"c":300}' 命令 SELECT='a,b'; echo $J | jq -c -s --arg P1 $SELECT '.[]|{a,b}' 产生 {"a":1,"b":10} {"a":2,"b":20} {"a":3,"b":30} 但此命令会产生意外的结果: SELECT='a,b'; echo $J |
J='{"a":1,"b":10,"c":100}
{"a":2,"b":20,"c":200}
{"a":3,"b":30,"c":300}'
命令
SELECT='a,b'; echo $J | jq -c -s --arg P1 $SELECT '.[]|{a,b}'
产生
{"a":1,"b":10}
{"a":2,"b":20}
{"a":3,"b":30}
但此命令会产生意外的结果:
SELECT='a,b'; echo $J | jq -c -s --arg P1 $SELECT '.[]|{$P1}'
{"P1":"a,b"}
{"P1":"a,b"}
{"P1":"a,b"}
如何让jq从字面上处理arg字符串
使用tostring会产生错误
SELECT='a,b'; echo $J | jq -c -s --arg P1 $SELECT '.[]|{$P1|tostring}'
jq: error: syntax error, unexpected '|', expecting '}' (Unix shell quoting
issues?) at <top-level>, line 1:
.[]|{$SELECT|tostring}
jq: 1 compile error
选择='a,b';echo$J | jq-c-s--arg P1$SELECT'.[]{$P1 | tostring}'
jq:错误:语法错误,意外的“|”,应为“}”(Unix shell引用)
问题?)第1行:
.[]|{$SELECT | tostring}
jq:1编译错误
SELECT需要是一个变量,而不是在脚本中硬编码。如果您确实希望数据被解析为语法。。。
这不是--arg
的合适用例。相反,将以下内容替换到代码中:
select='a,b'; jq -c -s '.[]|{'"$select"'}' <<<"$j"
如果您真的希望将数据解析为语法。。。
这不是--arg
的合适用例。相反,将以下内容替换到代码中:
select='a,b'; jq -c -s '.[]|{'"$select"'}' <<<"$j"
SELECT需要是一个变量,而不是在脚本中硬编码
假设要避免“代码注入”的风险,并且希望shell变量选择为一个简单的字符串,如“a,b”,然后考虑沿着您正在尝试的行的这个减少自由的解决方案:
J='{"a":1,"b":10,"c":100}'
SELECT='a,b'
echo "$J" |
jq -c --arg P1 "$SELECT" '
. as $in | $P1 | split(",") | map( {(.): $in[.]} ) | add'
输出:
{"a":1,"b":10}
SELECT需要是一个变量,而不是在脚本中硬编码
假设要避免“代码注入”的风险,并且希望shell变量选择为一个简单的字符串,如“a,b”,然后考虑沿着您正在尝试的行的这个减少自由的解决方案:
J='{"a":1,"b":10,"c":100}'
SELECT='a,b'
echo "$J" |
jq -c --arg P1 "$SELECT" '
. as $in | $P1 | split(",") | map( {(.): $in[.]} ) | add'
输出:
{"a":1,"b":10}
嗯?“字面意思”不是你想要的。你要求它被解析为代码(分为两个独立的标记),而不是文字。将
a,b
视为文字意味着将其视为一个三个字符的字符串,这正是jq
正在做的事情……也就是说:当前的行为远比你要求的行为正确;如果数据被视为代码,jq
永远不能在其输入不可信的情况下使用。顺便说一句,re:变量命名约定——请参阅POSIX规范,指出所有caps变量名称都用于对shell或操作系统有意义的变量,而小写名称则保留给应用程序使用(并且应用程序可以使用任何小写名称,而不会干扰操作系统工具的操作)。@CharlesDuffy:SELECT是在别处定义的bash变量,而不是不可信的输入。它正确地用于我的目的。哈?“字面上”不是您要求的。您要求它作为代码进行解析(分为两个单独的标记)将a,b
视为一个文本意味着将其视为一个三个字符的字符串,这正是jq
正在做的事情……也就是说:当前的行为远比您要求的行为正确;如果数据被视为代码,那么jq
永远无法在sit中使用其输入不受信任的情况下的评估。顺便说一句,re:变量命名约定——请参阅POSIX规范at,指出所有caps变量名称都用于对shell或操作系统有意义的变量,而小写名称保留供应用程序使用(并且应用程序可以使用任何小写名称,而不会有干扰操作系统工具操作的风险).@CharlesDuffy:SELECT是在别处定义的bash变量,不是不可信的输入。我正确地使用了它。这也是一个好选项,但选择的答案更简洁。这也是一个好选项,但选择的答案更简洁。