0

I have been trying to modify the accepted code provided by @peak in this thread: Split a JSON file into separate files. I'm very grateful for this answer, as it saved me many hours.

Both of the solutions provided in that thread produce exactly the results I expect and want within the resulting split files. However, the output files are named "$key.json". I would like the file name to be the data contained in the first field of the output file.

Each output file looks something like this:

{
  "name": "Bob Smith",
  "description": "(some descriptive text)",
  "image": "(link to an image file)",
  ...
}

I have spent several hours trying to figure out how to get the output file names to be "Bob Smith.json", "Jane Doe.json" etc., instead of "0.json", "1.json", etc. I have tried many different ways of modifying the output parameters printf "%s\n" "$item" > "/tmp/$key.json" and '{ print $2 > "/tmp/" $1 ".json" }' without any success. I am completely new to JQ, so I suspect that the solution may be very simple. But, without spending many more hours learning JQ, I don't think I will be able to find it on my own.

For your convenience, here are the solutions from the previous thread:

   jq -cr 'keys[] as $k | "\($k)\n\(.[$k])"' input.json |
  while read -r key ; do
    read -r item
    printf "%s\n" "$item" > "/tmp/$key.json"
  done

and

jq -cr 'keys[] as $k | "\($k)\t\(.[$k])"' input.json |
  awk -F\\t '{ print $2 > "/tmp/" $1 ".json" }'

Can someone who is proficient in JQ please give me a hint? Thank you.

1 Answers1

0

Blindly using .name as the basis of the filename might not be a great idea, so please adapt the following to your needs.

Assuming the input has the form as in the previous question, i.e.

{ "item1": { "name": "Bob Smith", ...}, ...}

you could use the following pipeline:

jq -cr '.[] | "\(.name)\t\(.)"' input.json |
  awk -F\\t '{ print $2 >> "/tmp/" $1 ".json" }' 
peak
  • 105,803
  • 17
  • 152
  • 177
  • This worked perfectly for me. Thank you. I had tried various uses of (.name) around or in place of $1. But, obviously, that wasn't the correct approach. Thanks again. – rickcrites Apr 25 '22 at 12:14