求助:使用JQ修改数组元素的部分内容(已能修改整体)
用JQ修改数组中字符串的部分内容
我懂你现在的困扰——之前能替换整个字符串,但想只改部分内容却摸不着头绪对吧?别慌,用JQ的字符串替换函数结合数组遍历就能轻松搞定!核心是用sub()或gsub()来定位并修改字符串里的特定片段,而不是替换整个值。
核心实现思路
- 用
map()遍历目标数组,对数组中的每个元素单独处理 - 用
sub("匹配规则"; "替换内容")替换第一个符合规则的片段;如果要替换所有匹配项,就用gsub() - 复杂场景下可以配合正则表达式,精准定位要修改的部分
示例演示
基础场景:替换固定片段
假设我们有一个存储文件路径的数组,需要把所有路径里的old_folder替换成new_folder:
输入JSON
{ "file_paths": [ "/usr/share/old_folder/config.ini", "/home/user/old_folder/photos/img.png", "/tmp/old_folder/temp.log" ] }
JQ命令
jq '.file_paths |= map(sub("old_folder"; "new_folder"))' input.json
如果你的字符串里有多个old_folder需要全部替换,把sub()换成gsub()即可:
jq '.file_paths |= map(gsub("old_folder"; "new_folder"))' input.json
期望输出
{ "file_paths": [ "/usr/share/new_folder/config.ini", "/home/user/new_folder/photos/img.png", "/tmp/new_folder/temp.log" ] }
进阶场景:正则匹配+捕获组修改
如果需要更精准的修改,比如给所有.md后缀的文件名加上draft_前缀:
输入JSON
{ "documents": [ "guide.md", "data.csv", "notes.md", "todo.txt" ] }
JQ命令
jq '.documents |= map(sub("^(.*)\\.md$"; "draft_\\1.md"))' input.json
这里用正则捕获组(.*)获取.md之前的文件名部分,再用\\1引用这个捕获内容,实现只修改前缀的需求。
期望输出
{ "documents": [ "draft_guide.md", "data.csv", "draft_notes.md", "todo.txt" ] }
关键注意事项
map()是处理数组的核心,确保每个元素都能被单独修改- 正则表达式在JQ里需要用
\\做转义(比如.要写成\\.) - 如果需要条件判断(比如只修改符合某条件的元素),可以结合
if-then-else,比如:jq '.documents |= map(if test("\\.md$") then sub("^(.*)"; "draft_\\1") else . end)' input.json
内容的提问来源于stack exchange,提问作者riddler
相关产品推荐
相关产品推荐

