如何使用 jq 递归地将函数应用于记录结构中的所有字符串
How to apply a function to all strings in record's structure recursively using jq
是否可以将对记录的递归转换应用到 return 同一记录,但映射所有 string
值?
例如:
{"x":"1", "a": {"b": 2, "c": ["a"]}, "d": {"e": "z"}}
应用了 "add prime" 的映射:
{"x":"1'", "a": {"b": 2, "c": ["a'"]}, "d": {"e": "z'"}}
我试过组合使用 recurse
、map
、string
和 select
,但运气不佳。有什么想法吗?
是,使用walk/1
。 jq manual.
中有说明
如果您的 jq 没有定义,这里是 builtin.jq 的定义:
# Apply f to composite entities recursively, and to atoms
def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
您也可以使用递归运算符轻松完成此操作:
jq '(.. | strings) += "\'"'
其中 ..
通过递归遍历输入的每个元素生成流,strings
过滤流中的字符串,+=
将右侧元素添加到左侧流和 "\'"
上的每个元素都是包含您要查找的 "prime" 的文字。
这是一个解决方案,它使用 paths/1 来识别字符串值并使用 reduce、setpath 和 getpath
reduce paths(type == "string") as $p (
.
; setpath($p; getpath($p) + "'")
)
是否可以将对记录的递归转换应用到 return 同一记录,但映射所有 string
值?
例如:
{"x":"1", "a": {"b": 2, "c": ["a"]}, "d": {"e": "z"}}
应用了 "add prime" 的映射:
{"x":"1'", "a": {"b": 2, "c": ["a'"]}, "d": {"e": "z'"}}
我试过组合使用 recurse
、map
、string
和 select
,但运气不佳。有什么想法吗?
是,使用walk/1
。 jq manual.
如果您的 jq 没有定义,这里是 builtin.jq 的定义:
# Apply f to composite entities recursively, and to atoms
def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
您也可以使用递归运算符轻松完成此操作:
jq '(.. | strings) += "\'"'
其中 ..
通过递归遍历输入的每个元素生成流,strings
过滤流中的字符串,+=
将右侧元素添加到左侧流和 "\'"
上的每个元素都是包含您要查找的 "prime" 的文字。
这是一个解决方案,它使用 paths/1 来识别字符串值并使用 reduce、setpath 和 getpath
reduce paths(type == "string") as $p (
.
; setpath($p; getpath($p) + "'")
)