/ / Como aplicar uma função a todas as strings na estrutura do registro usando recursivamente jq - json, recursion, jq

Como aplicar uma função a todas as strings na estrutura do registro recursivamente usando jq - json, recursion, jq

É possível aplicar uma transformação recursiva a um registro para retornar o mesmo registro, mas tendo todas string valores mapeados?

Por exemplo:

{"x":"1", "a": {"b": 2, "c": ["a"]}, "d": {"e": "z"}}

com um mapeamento de "add prime" aplicado:

{"x":"1"", "a": {"b": 2, "c": ["a""]}, "d": {"e": "z""}}

Eu tentei usar uma combinação de recurse, map, string e select com pouca sorte. Alguma ideia?

Respostas:

3 para resposta № 1

Você também pode fazer isso facilmente com o operador recurse:

jq "(.. | strings) += """"

Onde .. gera um fluxo iterando recursivamente por todos os elementos da entrada, strings filtra o fluxo para aqueles que são strings, += adiciona o elemento do lado direito a todos os elementos no fluxo do lado esquerdo e """ é um literal que contém o "primo" que você procura.


2 para resposta № 2

Sim, use walk/1. É explicado no manual jq.

Se o seu jq não o tiver definido, aqui está sua definição de 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;

0 para resposta № 3

Aqui está uma solução que usa caminhos / 1 para identificar valores de sequência e atualizá-los com reduzir, setpath e getpath

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