/ / Jak zastosować rekurencyjnie funkcję do wszystkich ciągów w strukturze rekordu przy użyciu jq - json, recursion, jq

Jak zastosować funkcję do wszystkich łańcuchów w strukturze rekordu rekurencyjnie, używając jq - json, rekursja, jq

Czy można zastosować rekurencyjną transformację do rekordu, aby zwrócić ten sam rekord, ale mając wszystko string wartości zmapowane?

Na przykład:

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

z zastosowanym odwzorowaniem „dodaj liczbę pierwszą”:

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

Próbowałem użyć kombinacji recurse, map, string i select przy odrobinie szczęścia. Jakieś pomysły?

Odpowiedzi:

3 dla odpowiedzi № 1

Możesz to również łatwo zrobić za pomocą operatora cyklicznego:

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

Gdzie .. generuje strumień, rekurencyjnie iterując po każdym elemencie wejściowym, strings filtruje strumień dla tych, którzy są łańcuchami, += dodaje prawy element do każdego elementu w lewym strumieniu i """ jest literałem zawierającym „liczbę pierwszą”, której szukasz.


2 dla odpowiedzi nr 2

Tak, użyj walk/1. Jest to wyjaśnione w jq manual.

Jeśli twoje jq nie ma go zdefiniowanego, oto jego definicja z 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 dla odpowiedzi № 3

Oto rozwiązanie, które wykorzystuje ścieżki / 1 do identyfikowania wartości ciągów i aktualizowania ich za pomocą redukować, setpath i getpath

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