Home > Blockchain >  JQ Split JSON in several files
JQ Split JSON in several files

Time:01-04

I'm new on this. And trying to spare or split a JSON in several files according to the content. The "name" of the target group is "root_rgs" and I'd like to have it in different files each one.

{
  "root_rgs": [
    "PROM_FD_ARCNA",
    "PROM_JOB_ICMP"
  ],
  "targets": [
    "HCC02155",
    "HCC09350",
    "HCC09321",
    "HCCEFACTORYWWW",
    "HCC9723"
  ]
}
{
  "root_rgs": [
    "PROM_FD_ARCNA",
    "PROM_JOB_WIN"
  ],
  "targets": [
    "LABTNSARWID236",
    "LABTNSARWID692",
    "VM00006"
  ]
}
{
  "root_rgs": [
    "PROM_FD_MTZ",
    "PROM_JOB_ICMP"
  ],
  "targets": [
    "TEIARWIN205",
    "TEIARWDB150",
    "TEIARWCXWA212"
  ]
}

Is it possible to generate something like:

ARCNA_ICMP.json

{
TARGETS:
        "HCC02155",
        "HCC09350",
        "HCC09321",
        "HCCEFACTORYWWW",
        "HCC9723"
}

ARCNA_WIN.json

{
TARGETS:
    "LABTNSARWID236",
    "LABTNSARWID692",
    "VM00006"
}

And so on...

Hope to be clear, thanks everyone!

CodePudding user response:

jq itself cannot write to files, neither to one nor to many. The shell calling jq, however, can. Therefore, any solution needs to orchestrate these two levels together.

One way would be to split up the task into small pieces like querying the data with jq to find out the number of documents, then iterate in the shell over that range. On each iteration, jq can be supplied with the current index and output the corresponding document, which can be saved by the shell.

Another way would be to have jq generate a script that is executable in the shell. As the other approach is quite straightforward, let's go with this one:

jq -r '
  "cat >"
    (.root_rgs | map(split("_")[-1]) | join("_")   ".json" | @sh)
    " <<<"
    ({targets} | tojson | @sh)
' input.json | bash

This produces for each document in the input stream a line using a Here String which is understood by bash

cat >'FILENAME' <<<'JSON'

This is then being executed by the shell by piping it into bash.

CodePudding user response:

Another possibility would be to combine one invocation of jq with one invocation of a utility like awk for writing the files:

jq -cr '(.root_rgs | "\(.[0]|sub("PROM_FD_";""))\(.[1]|sub("PROM_JOB";""))"),
        {TARGETS: .targets}' input.json |
  awk 'NR%2==1 {fn = $1 ".json"; next} {print $0 >> fn}'
  •  Tags:  
  • Related