我想将“CTE_LG_LL_OE”的值从“警告”替换为“就绪”
{ "abcd": { "aav": "on", "vvg": "iio7890_APPID", "ct": "b-tte", "eSL": true, "it": "https://%ght%.mjk.com/", "tpo": "i-1", "pd": false, "pm": false, "pr": "" }, "en": { "CTE_LG_LL_OE": "warn", "S_G_EL_OD": "INFO", "G_LG_EL_OVE": "info" }, "EN_HTTPS": false }
我可以使用以下命令在文件中找到相同的内容,但如何用一个衬垫命令替换它。
jq '.' /abc/temp/config.json | grep CTE_LG_LL_OE
答案1
到得到键的值,您将使用 JSON 感知工具,例如jq
而不是grep
.您这样做有几个原因:
- 您提取的值可能是编码的。如果您将其与( ) 选项一起使用,该
jq
工具将为您解码。-r
--raw-output
- 使用时
grep
不区分值和键,因此您可能会意外提取不打算提取的数据。
CTE_LG_LL_OE
提取顶级条目中键的值en
:
jq -r '.en.CTE_LG_LL_OE' file
将值设置为字符串ready
并将结果文档写入文件new-file
:
jq '.en.CTE_LG_LL_OE |= "ready"' file >new-file
该|=
运算符是“更新运算符”,它采用左侧键的“路径”和右侧键的新值。
要设置 shell 变量的值:
jq --arg newval "$newvalue" '.en.CTE_LG_LL_OE |= $newval' file >new-file
这会创建一个从 shell 变量jq
调用的变量,然后我们在表达式中使用它。变量中的值将自动由 .json 编码。$newval
newvalue
jq
jq
为了便于阅读,请稍微间隔一下(假设这是 shell 脚本的一部分,因为问题标记为shell脚本):
jq --arg newval "$newvalue" \
'.en.CTE_LG_LL_OE |= $newval' file >new-file
对文件进行就地编辑(jq
本身不支持就地编辑):
tmpfile=$(mktemp)
cp file "$tmpfile" &&
jq --arg newval "$newvalue" \
'.en.CTE_LG_LL_OE |= $newval' "$tmpfile" >file &&
rm -f "$tmpfile"
作为一次衬线:
tmpfile=$(mktemp); cp file "$tmpfile" && jq --arg newval "$newvalue" '.en.CTE_LG_LL_OE |= $newval' "$tmpfile" >file && rm -f "$tmpfile"
如果您不确定在哪里在文档结构中,CTE_LG_LL_OE
键位于并且只想更新值全部 CTE_LG_LL_OE
具有值的键warn
:
jq '
(
.. |
select(type == "object" and .CTE_LG_LL_OE? == "warn").CTE_LG_LL_OE
) |= "ready"' file
这会递归地检查整个文档中的所有键和值。它找到所有具有CTE_LG_LL_OE
带有 evalue 的键的对象warn
,并将它们更新为ready
。换行符只是为了可读性。
该值可以像以前一样从 shell 变量中获取:
jq --arg newval "$somevariable" '
(
.. |
select(type == "object" and .CTE_LG_LL_OE? == "warn").CTE_LG_LL_OE
) |= $newval' file
显然,这也可以与就地编辑相结合,如本答案的前半部分所示。
答案2
对于 file.json 中的示例内容,以下单行代码有效:
cat file.json | jq '.en.CTE_LG_LL_OE = "ready"' | tee file.json
分解一下:
cat …
将 file.json 的内容复制到标准输出 (stdout)。|
将此输出发送到下一个命令的标准输入 (stdin)。jq '.en.CTE_LG_LL_OE = "ready"'
具有 jq 所谓的“过滤器”('.en.CTE_LG_LL_OE = "ready"'
将特定值分配给特定键),但确实不是指定任何输入文件。这会导致jq
从标准输入读取其输入。| tee
将输出发送jq
到tee
命令,该命令将其写入标准输出和指定的文件。
我对自己的行为感到困惑后发现了这个问题jq
。由于某种原因(比较答案https://stackoverflow.com/questions/48964305/write-output-to-a-file-after-piped-to-jq) 输出重定向不是工作,jq
文件也不会自行读取。简而言之,以下都不起作用;其中任何一个都会截断 file.json,使其完全为空:
jq '.en.CTE_LG_LL_OE = "ready"' file.json >file.json
jq '.en.CTE_LG_LL_OE = "ready"' file.json | tee file.json
cat file.json | jq '.en.CTE_LG_LL_OE = "ready"' >file.json
某些标准命令行选项可能会改变此行为。