/ / Come applicare una funzione a tutte le stringhe nella struttura del record in modo ricorsivo usando jq - json, recursion, jq

Come applicare una funzione a tutte le stringhe nella struttura del record in modo ricorsivo usando jq - json, recursion, jq

È possibile applicare una trasformazione ricorsiva a un record per restituire lo stesso record, ma avendo tutto string valori mappati?

Per esempio:

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

con una mappatura di "aggiungi prime" applicata:

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

Ho provato a usare una combinazione di recurse, map, string e select con poca fortuna. Qualche idea?

risposte:

3 per risposta № 1

Puoi anche farlo facilmente con l'operatore di recurse:

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

Dove .. genera uno stream ripetendo in modo ricorsivo ogni elemento dell'input, strings filtra lo stream per coloro che sono stringhe, += aggiunge l'elemento destro a ogni elemento sul flusso sinistro e """ è un letterale contenente il "primo" che cerchi.


2 per risposta № 2

Sì, usa walk/1. È spiegato nel manuale jq.

Se il tuo jq non lo ha definito, ecco la sua definizione da 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 per risposta № 3

Ecco una soluzione che utilizza tracciati / 1 per identificare i valori di stringa e aggiornarli con ridurre, SetPath e GetPath

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