Narwhal Narwhal - 1 month ago 15
Perl Question

How to replace pattern range using awk or sed

Some people format their JSON files where all the main data elements are inside an array. I want to promote the array elements to be json objects.

In other words ... I want to take any generic text file like this:


{"foods":[{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup, 6 spears","food":"Asparagus"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup","food":"Beans, green"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup cooked","food":"Bok choy/Chinese cabbage (Choi sum)"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup","food":"Broccoli"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup, 4 sprouts","food":"Brussels sprouts"},{"fgid":"vf","fgcat_id":"2","srvg_sz":"125 mL, ½ cup, 1 large","food":"Carrots"}]}


and find replace the range of text from the first "{" to the first "[" and just replace it with "{{", and (in a separate command?) at the end replace the "]" so that it looks like this:


{{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup, 6 spears","food":"Asparagus"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup","food":"Beans, green"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup cooked","food":"Bok choy/Chinese cabbage (Choi sum)"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup","food":"Broccoli"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup, 4 sprouts","food":"Brussels sprouts"},{"fgid":"vf","fgcat_id":"2","srvg_sz":"125 mL, ½ cup, 1 large","food":"Carrots"}}


But I would like this to be for any similar file so I don't know the length of the "foods" text (or sometimes there are other elements before the array that I also want to wipe out before the first "[" starts). This would help me deal with Open Data from the Canadian government as all the JSON is in one object in an array. Thank you. I would be happy to use either sed or awk.

Answer

Something like this will do the trick I think:

#!/usr/bin/env perl

use strict;
use warnings;
use JSON;
use Data::Dumper;

my $json_str =
  '{"foods":[{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup, 6 spears","food":"Asparagus"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup","food":"Beans, green"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup cooked","food":"Bok choy/Chinese cabbage (Choi sum)"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup","food":"Broccoli"},{"fgid":"vf","fgcat_id":"1","srvg_sz":"125 mL, ½ cup, 4 sprouts","food":"Brussels sprouts"},{"fgid":"vf","fgcat_id":"2","srvg_sz":"125 mL, ½ cup, 1 large","food":"Carrots"}]}';

my $json_obj = from_json($json_str);
print Dumper \$json_obj;
my $json_arr = $json_obj -> {foods}; 
print to_json ( $json_arr, { pretty => 1 } );

I'm actually fairly sure your second example isn't actually valid JSON, as you can't do a 'sort of array' without using [].