On Thu, Oct 24, 2024 at 02:58:00AM +1100, Viktor Dukhovni via mailop wrote:
> The below works if it is not too costly to hold the entire thing in > memory. It can be optimised for streaming, but the "jq" script becomes > harder to understand. > The streaming version (execute as: jq --stream -nr -f script.jq input.json) is below. This also filters to the values prior to output, rejecting data with embedded control characters or addresses with something other than hex digits '.' or ':' (plausibly, but not necessarily v4 or v6 addresses). The sample input therefore needs more realistic addresses (no XXX). -- Viktor. def init: { ix: -1, wip: {} }; def update($pv): $pv[0][0] as $ix | $pv[0][1:] as $p | $pv[1] as $v | if .ix != $ix or $p == [] then .done = .wip | .wip = { addrs: [] } else .done = {} end | .ix = $ix | if ([$v, $p[-1]] | map(type)) == ["string", "string"] then if $p[0] == "client" then .wip |= setpath($p; $v) elif $p[0] == "ips" and $p[-2] == "active" then .wip.addrs += [[$p[-1], $v]] else . end else . end; def extract: .done | select(.client.name? | type == "string" and . != "") | select(.client.complaint_address? | type == "string" and . != "") | select(.addrs | type == "array" and . != []) | select(.client.name | test("^[ -~]*$")) | select(.client.complaint_address | test("^[ -~]*$")) | select(.addrs | all(.[0] | test("^[a-fA-F0-9.:]*$"))) | select(.addrs | all(.[1] | test("^[ -~]*$"))) | ( "## Name: \(.client.name)" , "## Abuse: \(.client.complaint_address)" , ( .addrs[] | ( "# \(.[1])" , "\(.[0]) permit" ) ) , "" ); foreach inputs as $pathval (init; update($pathval); extract) _______________________________________________ mailop mailing list mailop@mailop.org https://list.mailop.org/listinfo/mailop