Usando sed para compactar matrizes JSON

2

Eu tenho uma saída JSON no seguinte formato:

{
  "DaysCfg": {
    "Range": {
      "lowerDate": "2017-07-28T00:00:00.000-04:00",
      "upperDate": "2017-08-04T00:00:00.000-04:00"
    },
    "DaysInPeriod": 8,
    "DaysToSchedule": [
      0,
      1,
      2,
      3,
      4,
      5,
      6
    ]
  },
  "DepartmentsID": [
    138837,
    139734,
    141934,
    142436,
    149687,
    151049
  ],
  "EmployeesID": [
    5039,
    5170,
    5889,
    6051,
    6236,
    7208,
    7281,
    8776,
    8781,
    8936,
    9261
  ],
  "EndDate": "2017-08-03T23:59:00.000-04:00",
  "IntervalSize": 15,
  "IsActivitiesEnabled": true,
  "ModifyExisting": false,
  "OrignId": 134721,
  "PrimaryOption": 0,
  "SchoolDays": [],
  "ScChanges": [],
  "StartDate": "2017-07-28T00:00:00.000-04:00",
  "ZonesToSchedule": [
    5,
    4,
    6,
    3,
    3,
    3,
    2,
    14
  ]
}

Como não posso alterar o programa que o imprime, preciso usar sed (ou awk ) para compactar matrizes JSON. O resultado desejável seria:

{
  "DaysCfg": {
    "Range": {
      "lowerDate": "2017-07-28T00:00:00.000-04:00",
      "upperDate": "2017-08-04T00:00:00.000-04:00"
    },
    "DaysInPeriod": 8,
    "DaysToSchedule": [0, 1, 2, 3, 4, 5, 6]
  },
  "DepartmentsID": [138837, 139734, 141934, 142436, 149687, 151049],
  "EmployeesID": [5039, 5170, 5889, 6051, 6236, 7208, 7281, 8776, 8781, 8936, 9261],
  "EndDate": "2017-08-03T23:59:00.000-04:00",
  "IntervalSize": 15,
  "IsActivitiesEnabled": true,
  "ModifyExisting": false,
  "OrignId": 134721,
  "PrimaryOption": 0,
  "SchoolDays": [],
  "ScChanges": [],
  "StartDate": "2017-07-28T00:00:00.000-04:00",
  "ZonesToSchedule": [5, 4, 6, 3, 3, 3, 2, 14]
}

Eu mesmo tentei criar um script sed , mas ele é apenas parcialmente cozido e não funciona totalmente:

sed -r -e :a -e '/^ *[]}],*$/!N; /": \[/s/\n +//; ta' -e 'P;D'

Por favor me ajude. THX.

    
por xpt 28.07.2017 / 19:01

1 resposta

3

Eu editei seu sed, espero que isso ajude.

sed -r '/\[$/ {:a;N;s/\]/&/;Ta;s/\n +//g}'

sed -r '

# sed will apply the commands between '{}' only to lines that matches the address '/\[$/'.
/\[$/ {

# Set a mark with label 'a'.
:a

# N command, it appends a '\n' to the pattern space,
# reads the next line of the input (file,stdin) and appends it to the pattern space.
N

# Substitute ']' for itself. If the substitution isn't made (if there isn't a ']' on the
# pattern space), the 'T' command jumps to the 'a' label.
# Here is the loop to put some lines (or all lines of a file) in the same line.
# While there isn't a ']' in the pattern space (which is the last line OP wants to put
# on the same line), sed will append '\n<next line>' to the pattern space.
s/\]/&/
Ta

# When the substitution is made, sed leaves the loop and applies other commands.
# Substitute all occurrences (g flag) of new line character (with any
# spaces after) for nothing.
s/\n +//g
}'
    
por 31.07.2017 / 03:58