文章目录
jq工具安装在线安装离线安装 使用方法读取和修改 JSON 文件中的一个字段(麻烦)读取和修改 JSON 文件中的一个字段(简洁)1读取和修改 JSON 文件中的一个字段(简洁)20329 这个稍复杂,读取json并替换另一个json字段一部分,加入了正则表达式jq内置函数`|=` 和 `sub``|=`:更新某个字段的值`sub`:替换字符串关于正则表达式`[0-9]+` 其他(直接把两个替换做到一起) jq的编译jq工具安装
在线安装
sudo apt-get install jq # Ubuntu 系统
离线安装
如果你的服务器没有联网,则无法使用包管理器来安装 jq 工具。不过,你仍然可以通过以下步骤手动安装 jq 工具:
在另一台联网的计算机上下载 jq 的二进制文件。可以在 jq 的官方网站上找到适合你服务器架构的二进制文件。例如,如果你的服务器是 x86 64 位架构,则可以在以下链接中下载 jq 的二进制文件:
/stedolan/jq/releases/download/jq-1.6/jq-linux64
其他版本下载点这:/jqlang/jq/releases/
将下载的二进制文件传输到您的服务器。你可以使用 scp 命令或其他文件传输工具将文件传输到服务器。例如,如果你的服务器的 IP 地址是 192.168.0.100,你可以使用以下命令将文件传输到服务器:
scp jq-linux64 user@192.168.0.100:/home/user/
其中,user 是你在服务器上的用户名,/home/user/
是你在服务器上的目标目录。
在服务器上设置 jq 的执行权限。使用以下命令将 jq 文件设置为可执行:
chmod +x /home/user/jq-linux64
将 jq 文件复制到你的 PATH 路径中。使用以下命令将 jq 文件复制到/usr/local/bin/
目录中:
sudo cp /home/user/jq-linux64 /usr/local/bin/jq
现在,你可以在服务器上使用 jq 工具了。
使用方法
读取和修改 JSON 文件中的一个字段(麻烦)
#!/bin/bash# 读取 JSON 文件内容json=$(cat example.json)# 使用 jq 工具修改其中的字段new_json=$(echo $json | jq '.field_to_modify = "new_value"')# 将修改后的 JSON 内容写回文件中echo $new_json > example.json
在上面的示例脚本中,我们首先使用 cat 命令读取 JSON 文件 example.json 的内容,并将其存储在一个变量 json 中。接下来,我们使用 jq 工具修改 JSON 中的一个字段,例如将名为 field_to_modify 的字段的值修改为 “new_value”。最后,我们将修改后的 JSON 内容写回到原始文件中。
请注意,使用 jq 工具需要在系统上安装该工具。如果您的系统上没有安装 jq,您可以使用以下命令进行安装:
读取和修改 JSON 文件中的一个字段(简洁)1
需求:
将json文件ky_ai_solution.json文件中的ServerIpPort的ip改成192.168.1.100,json文件内容如下:
(ky_ai_solution.json)
{"LocalIpPort": "0.0.0.0:17751","ServerIpPort": "192.168.1.140:7777","aiSolution": 2,"algoAppPath": "cw","isapiPath": "kyai","packagePath": "/ky/alg/"}
(run.sh)
#!/bin/bash# 读取 json 文件并修改 ServerIpPort 字段jq '.ServerIpPort = "192.168.1.100:7777"' ky_ai_solution.json > tmp.json && mv tmp.json ky_ai_solution.json
这个脚本使用了 jq 工具来读取和修改 JSON 文件。首先,它将 ServerIpPort 字段的值更改为 192.168.1.100:7777,然后将修改后的 JSON 内容重定向到临时文件 tmp.json 中。最后,它使用 mv 命令将 tmp.json 文件重命名为 ky_ai_solution.json,以覆盖原始文件。
请确保将脚本中的文件名 ky_ai_solution.json 替换为你实际使用的 JSON 文件名。另外,如果你需要修改不同的字段或值,请相应地修改 jq 命令中的参数。
读取和修改 JSON 文件中的一个字段(简洁)2
需求:
将json文件ky_ai_solution.json文件中的CameraID的改成192dfdsfdsfdsf,json文件内容如下:
(ky_ai_solution.json)
{"CameraInfos": [{"CameraID": "CAMERAID_001","Running": "1","AlgorithmName": "AlgoType1","SubAlgoName": "behavior.structured.data","RtspAddress": "rtsp://admin:xxx@192.168.1.90:554/Streaming/Channels/101","DeptID": "Dept_001","AddrID": "Addr_001"}]}
(run.sh)
#!/bin/bash# 读取 json 文件并修改 CameraID 字段jq '.CameraInfos[0].CameraID = "192dfdsfdsfdsf"' ky_ai_solution.json > tmp.json && mv tmp.json ky_ai_solution.json
这个脚本使用了 jq 工具来读取和修改 JSON 文件。它先选择 CameraInfos 数组中的第一个元素,然后将 CameraID 字段的值更改为 192dfdsfdsfdsf。最后,它将修改后的 JSON 内容重定向到临时文件 tmp.json 中,并使用 mv 命令将 tmp.json 文件重命名为 ky_ai_solution.json,以覆盖原始文件。
请注意,如果 CameraInfos 数组中有多个元素,则需要根据需要修改 jq 命令以处理所有元素。另外,如果你需要修改不同的字段或值,请相应地修改 jq 命令中的参数。
0329 这个稍复杂,读取json并替换另一个json字段一部分,加入了正则表达式
我有一个config.json,内容如下:
{
“ServerIp”: “192.168.1.140”
}
还有一个param.txt文件,内容如下:
{
“engineAddress”: “192.168.1.91:8”,
“mediaServerAddress”: “192.168.1.91:17080”,
“logLevel”: “INFO”,
“localAddress”: “0.0.0.0:23031”,
“queueSize”: 1024
}
我需要一个shell脚本,用jq工具将config.json文件中ServerIp字段的值提取出来,然后将它替换param.txt中的engineAddress和mediaServerAddress中的ip
#!/bin/bash# 从config.json文件中读取ServerIp字段的值server_ip=$(jq -r '.ServerIp' config.json)# 替换param.txt文件中engineAddress字段中的ip部分jq --arg ip "$server_ip" '.engineAddress |= sub("[^:]+"; $ip)' param.txt > tmp.json# 替换更新后的内容mv tmp.json param.txt# 替换param.txt文件中mediaServerAddress字段中的ip部分jq --arg ip "$server_ip" '.mediaServerAddress |= sub("[^:]+"; $ip)' param.txt > tmp.json# 替换更新后的内容mv tmp.json param.txt
解释一下这个脚本的几个步骤:
使用jq工具从config.json文件中读取ServerIp字段的值,并将其保存在server_ip变量中。
使用jq工具更新param.txt文件中engineAddress字段的值。这里使用了–arg选项将server_ip变量传递给jq,然后使用sub函数将engineAddress字段中原有的ip部分替换为server_ip变量中保存的值。
将更新后的内容保存在一个临时文件中,然后将其覆盖原文件。
使用jq工具更新param.txt文件中mediaServerAddress字段的值。这里同样使用了–arg选项将server_ip变量传递给jq,然后使用sub函数将mediaServerAddress字段中原有的ip部分替换为server_ip变量中保存的值。
将更新后的内容保存在一个临时文件中,然后将其覆盖原文件。
jq内置函数|=
和sub
|=
:更新某个字段的值
|=
表示更新某个字段的值。具体而言,它接受两个参数:第一个参数是要更新的字段的名称或路径,第二个参数是新的值或更新字段的表达式。如果第二个参数是一个表达式,则表达式的值将被用作新的字段值。如果第二个参数是一个常量,则常量将被用作新的字段值。
例如,假设我们有一个JSON对象 obj,它有一个字段 foo 的值为 10。要将 foo 的值加上 5,可以使用以下命令:
echo '{"foo": 10}' | jq '.foo |= .+5'
结果:
{"foo": 15}
这里的|= .+5
就是一个更新字段的表达式,它表示将原来的字段值加上 5。
sub
:替换字符串
sub 函数是用来替换字符串的。它接受两个参数:第一个参数是正则表达式,第二个参数是要替换成的字符串。具体而言,它会在输入的字符串中查找与正则表达式匹配的部分,并将其替换为指定的字符串。
例如,假设我们有一个字符串"foo:123"
,我们想将其中的数字替换为"456"
,可以使用以下命令:
echo 'foo:123' | jq 'sub("[0-9]+"; "456")'
结果:
foo:456
关于正则表达式[0-9]+
[0-9]+
是一个正则表达式,表示匹配一个或多个数字字符。具体而言,它包含两个部分:
[0-9]
表示匹配任意一个数字字符,也可以写成\d
。
+
表示匹配前面的字符(这里是数字字符)一次或多次。
因此,[0-9]+
表示匹配一个或多个数字字符,例如 123、4567 等。在 sub 函数中,它被用来匹配输入字符串中的数字部分,以便进行替换。
其他(直接把两个替换做到一起)
# 获取jq工具路径JQ_TOOL="${SCRIPT_PATH}/${DEPLOY_DIR}/tools/jq/jq-linux64"# 读取ServerIp字段的值NEW_SERVER_IP=$(${JQ_TOOL} -r '.ServerIp' "${SCRIPT_PATH}/${CONFIG_FILE}")# 校验ServerIp# 将NEW_SERVER_IP写入ky_ai_solution.jsonOLD_SERVER_PORT=$(${JQ_TOOL} -r '.ServerIpPort' "${KY_AI_SOLUTION_JSON_PATH}" | awk -F':' '{print $2}')NEW_SERVER_IP_PORT="${NEW_SERVER_IP}:${OLD_SERVER_PORT}"${JQ_TOOL} ".ServerIpPort = \"${NEW_SERVER_IP_PORT}\"" "${KY_AI_SOLUTION_JSON_PATH}" > tmp.json && mv tmp.json "${KY_AI_SOLUTION_JSON_PATH}" && chmod 777 "${KY_AI_SOLUTION_JSON_PATH}"
上面最后三句可直接合并为一句:
${JQ_TOOL} --arg ip "$NEW_SERVER_IP" '.ServerIpPort |= sub("[^:]+"; $ip)' "${KY_AI_SOLUTION_JSON_PATH}" >tmp.txt &&mv tmp.txt "${KY_AI_SOLUTION_JSON_PATH}" &&chmod 777 "${KY_AI_SOLUTION_JSON_PATH}"
jq的编译
x86版本的我直接下载jq-linux64下来就能跑了:
但是在arm下,还得自行编译,我下载这个源码:
然后拷贝到系统里,tar -xzf jq-1.6.tar.gz
解压:
然后我参考里面这个readme.md:
然后执行这几条编译命令:
执行这四条就可以了(一开始没执行autoreconf -fi给我报了一堆错误):
autoreconf -fi # if building from git./configure --with-oniguruma=builtinmake -j8make check
然后最终可执行文件生成在这:
我把它拷贝到目标位置再改名成jq-linux64
注意,我不太清楚我们arm NX ubuntu20.04和ubuntu18.04的盒子有啥区别,我把在20.04上编译生成的文件拷贝到18.04上,还用不了。。。