使用jq修改JSON [英] Modifying JSON by using jq
问题描述
我想使用Linux命令行修改JSON文件.
I want to modify a JSON file by using the Linux command line.
我尝试了以下步骤:
[root@localhost]# INPUT="dsa"
[root@localhost]# echo $INPUT
dsa
[root@localhost]# CONF_FILE=test.json
[root@localhost]# echo $CONF_FILE
test.json
[root@localhost]# cat $CONF_FILE
{
"global" : {
"name" : "asd",
"id" : 1
}
}
[root@localhost]# jq -r '.global.name |= '""$INPUT"" $CONF_FILE > tmp.$$.json && mv tmp.$$.json $CONF_FILE
jq: error: dsa/0 is not defined at <top-level>, line 1:
.global.name |= dsa
jq: 1 compile error
所需的输出:
[root@localhost]# cat $CONF_FILE
{ "global" : {
"name" : "dsa",
"id" : 1 } }
推荐答案
您唯一的问题是传递给jq
的脚本引用不正确.
Your only problem was that the script passed to jq
was quoted incorrectly.
在您的特定情况下,将单个双引号字符串与嵌入的\
转义的"
实例一起使用可能是最简单的:
In your particular case, using a single double-quoted string with embedded \
-escaped "
instances is probably simplest:
jq -r ".global.name = \"$INPUT\"" "$CONF_FILE" > tmp.$$.json && mv tmp.$$.json "$CONF_FILE"
但是,通常, chepner的有用答案显示了将shell变量引用直接嵌入到其中的更健壮的选择脚本:使用 --arg
选项传递值作为jq
变量允许单引号 ,这是更好的选择,因为它避免了shell预先扩展了哪些元素的混淆,并且避免了转义应传递给jq
的$
实例的需要.
Generally, however, chepner's helpful answer shows a more robust alternative to embedding the shell variable reference directly in the script: Using the --arg
option to pass a value as a jq
variable allows single-quoting the script, which is preferable, because it avoids confusion over what elements are expanded by the shell up front and obviates the need for escaping $
instances that should be passed through to jq
.
也:
- 只需
=
就足以分配值;虽然|=
(所谓的更新运算符)也可以工作,但在这种情况下它的作用与=
相同,因为RHS是 literal ,而不是引用LHS的表达式-请参阅手册. - 您应该常规地将shell变量引用双引号,并且应该避免使用全大写的变量名,以便
- Just
=
is sufficient to assign the value; while|=
, the so-called update operator, works too, it behaves the same as=
in this instance, because the RHS is a literal, not an expression referencing the LHS - see the manual. - You should routinely double-quote your shell-variable references and you should avoid use of all-uppercase variable names in order to avoid conflicts with environment variables and special shell variables.
关于为什么您的报价无效:
'.global.name |= '""$INPUT""
由以下标记组成:
- 字符串文字
.global.name |=
(由于单引号) - 字符串文字
""
-即空字符串-在jq
看到脚本之前,shell将引号除去 - 对
$INPUT
变量的不带引号的引用(使它的值易于分词和通配). - 文字
""
的另一个实例.
- String literal
.global.name |=
(due to single-quoting) - String literal
""
- i.e., the empty string - the quotes will be removed by the shell beforejq
sees the script - An unquoted reference to variable
$INPUT
(which makes its value subject to word-splitting and globbing). - Another instance of literal
""
.
使用您的样本值,jq
最终看到以下字符串作为其脚本:
With your sample value, jq
ended up seeing the following string as its script:
.global.name |= dsa
如您所见,双引号丢失了,导致jq
将dsa
解释为函数名而不是字符串文字,并且由于没有将参数传递给(函数dsa
存在,jq
的错误消息将其引用为dsa/0
-没有(0
)参数的函数.
As you can see, the double quotes are missing, causing jq
to interpret dsa
as a function name rather than a string literal, and since no argument was passed to (non-existent) function dsa
, jq
's error message referenced it as dsa/0
- a function with no (0
) arguments.
这篇关于使用jq修改JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!