如何使用 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'"}}

我试过组合使用 recursemapstringselect,但运气不佳。有什么想法吗?

是,使用walk/1jq 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 来识别字符串值并使用 reducesetpathgetpath

reduce paths(type == "string") as $p (
    .
  ; setpath($p; getpath($p) + "'")
)