如何使用awk或sed替换模式范围

时间:2016-10-22 15:58:30

标签: perl awk replace sed

有些人格式化他们的JSON文件,其中所有主要数据元素都在数组中。我想将数组元素提升为json对象。

换句话说......我想要采用这样的通用文本文件:

  

{“食物”:[{“fgid”:“vf”,“fgcat_id”:“1”,“srvg_sz”:“125毫升,½杯,6支长矛”,“食物”:“芦笋”}, {“fgid”:“vf”,“fgcat_id”:“1”,“srvg_sz”:“125 mL,½cup”,“food”:“Beans,green”},{“fgid”:“vf”,“ fgcat_id“:”1“,”srvg_sz“:”125毫升,½杯煮熟“,”食物“:”白菜/大白菜(彩和)“},{”fgid“:”vf“,”fgcat_id“: “1”,“srvg_sz”:“125 mL,½杯”,“食物”:“西兰花”},{“fgid”:“vf”,“fgcat_id”:“1”,“srvg_sz”:“125 mL, ½杯,4豆芽“,”食物“:”布鲁塞尔豆芽“},{”fgid“:”vf“,”fgcat_id“:”2“,”srvg_sz“:”125毫升,½杯,1大“,”食品 “:” 胡萝卜“}]}

并找到替换第一个“{”第一个“[”>的文字范围,只需将其替换为“{{”,并且(在单独的命令?)最后替换“]”,使它看起来像这样:

  

{{“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毫升,½杯煮熟“,”食物“:”白菜/大白菜(彩和)“},{”fgid“:”vf“,”fgcat_id“:”1“,” srvg_sz“:”125毫升,½杯“,”食物“:”西兰花“},{”fgid“:”vf“,”fgcat_id“:”1“,”srvg_sz“:”125毫升,½杯,4个豆芽“,”食物“:”布鲁塞尔豆芽“},{”fgid“:”vf“,”fgcat_id“:”2“,”srvg_sz“:”125毫升,½杯,1大“,”食物“:”胡萝卜“}}

但我希望这可以用于任何类似的文件,所以我不知道“食物”文本的长度(或者有时在阵列之前还有其他元素,我也想在第一个之前消灭“[ “开始)。这将有助于我处理来自加拿大政府的开放数据,因为所有JSON都在一个数组中的一个对象中。谢谢。我很乐意使用sed或awk。

2 个答案:

答案 0 :(得分:1)

这样的事情我会想到:

#!/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 } );

我实际上相当确定你的第二个例子实际上并不是有效的JSON,因为你不能做一个类型的数组'不使用[]

答案 1 :(得分:0)

试试这个 -

sed -e '1s/{/{{/' -e '$s/\(.*\)]/\1/'

以下是解释: -e用于使用多个sed操作 1s是选择第一行 $ s是选择最后一行 (。*)] / \ 1替换[。

的最后一次出现