morris__
morris__

Reputation: 19

how to convert txt to json?

i try use jq convert was successful, but I didn't get the results I wanted. I tried to get the results I wanted, but it's hard.

jq -Rs '[ split("\n")[] | select(length > 0) | split(" ") |  {group:.[0], instnace: .[1], value: .[2]} ]' input.txt

original txt file.. There are IP addresses and values ​​from cpu20 to 46 in total

cpu20 10.0.20.1 12
cpu20 10.0.20.1 22
cpu20 10.0.20.1 13
cpu20 10.0.20.1 11
cpu20 10.0.20.1 14

....~cpu46

It's the result of the way I tried. output json

{
    "group": "cpu-46",
    "instnace": "10.0.46.94",
    "value": "10"
  },
  {
    "group": "cpu-46",
    "instnace": "10.0.46.95",
    "value": "10"
  },
  {
    "group": "cpu-46",
    "instnace": "10.0.46.96",
    "value": "11"
  },
  {
    "group": "cpu-46",
    "instnace": "10.0.46.97",
    "value": "8"
  },
  {
    "group": "cpu-46",
    "instnace": "10.0.46.98",
    "value": "11"
  },
  {
    "group": "cpu-46",
    "instnace": "10.0.46.99",
    "value": "11"
  },
  {
    "group": "cpu-46",
    "instnace": "10.0.46.100",
    "value": "8"
  }

What should I do to get the results as follows?

    {
  "CPU20": [
    { "instance": "10.0.20.1", "value": 12 },
    { "instance": "10.0.20.2", "value": 22 },
    { "instance": "10.0.20.3", "value": 13 },
    { "instance": "10.0.20.4", "value": 11 },
    { "instance": "10.0.20.5", "value": 14 }
  ],
  "CPU21": [
    { "instance": "10.0.21.1", "value": 15 },
    { "instance": "10.0.21.2", "value": 24 },
    { "instance": "10.0.21.3", "value": 21 },
    { "instance": "10.0.21.4", "value": 15 },
    { "instance": "10.0.21.5", "value": 16 }
  ],
  "CPU22": [
    { "instance": "10.0.22.1", "value": 12 },
    { "instance": "10.0.22.2", "value": 18 },
    { "instance": "10.0.22.3", "value": 19 },
    { "instance": "10.0.22.4", "value": 12 },
    { "instance": "10.0.22.5", "value": 13 }
  ],
  "CPU23": [
    { "instance": "10.0.20.1", "value": 17 },
    { "instance": "10.0.20.2", "value": 15 },
    { "instance": "10.0.20.3", "value": 21 },
    { "instance": "10.0.20.4", "value": 22 },
    { "instance": "10.0.20.5", "value": 25 }
  ]
}

Upvotes: 1

Views: 602

Answers (2)

pmf
pmf

Reputation: 36088

Using group_by and map

jq -Rn '
  [inputs | select(. != "") / " "]
  | group_by(.[0])
  | map({(.[0][0]): map({instance: .[1], value: .[2]})})
  | add
'

Demo

Using reduce

jq -Rn '
  reduce (inputs | select(. != "") / " ") as [$cpu, $instance, $value] ({};
    .[$cpu] += [{$instance, $value}]
  )
'

Demo
Improved by @JeffMercado

Upvotes: 5

glenn jackman
glenn jackman

Reputation: 246807

A scripting language like ruby would work here as well:

ruby -rjson -e '
  data = Hash.new {|h, k| h[k] = []}
  File.new(ARGV.shift).each {|line|
    cpu, ip, num = line.split
    data[cpu] << {instance: ip, value: num.to_i}
  }
  puts JSON.dump(data)
' input.txt
{"CPU20":[{"instance":"10.0.20.1","value":12},{"instance":"10.0.20.2","value":22},{"instance":"10.0.20.3","value":13},{"instance":"10.0.20.4","value":11},{"instance":"10.0.20.5","value":14}],"CPU21":[{"instance":"10.0.21.1","value":15},{"instance":"10.0.21.2","value":24},{"instance":"10.0.21.3","value":21},{"instance":"10.0.21.4","value":15},{"instance":"10.0.21.5","value":16}],"CPU22":[{"instance":"10.0.22.1","value":12},{"instance":"10.0.22.2","value":18},{"instance":"10.0.22.3","value":19},{"instance":"10.0.22.4","value":12},{"instance":"10.0.22.5","value":13}],"CPU23":[{"instance":"10.0.20.1","value":17},{"instance":"10.0.20.2","value":15},{"instance":"10.0.20.3","value":21},{"instance":"10.0.20.4","value":22},{"instance":"10.0.20.5","value":25}]}

Upvotes: 0

Related Questions