Home > Software design >  Text file to json using JQ command
Text file to json using JQ command

Time:10-19

I have a text file with data like below:

6111119268639|22|65024:3|2000225350|Samsung|ADD|234534643645|REMOVE|5645657|65067:3|Apple|ADD|234534643645|REMOVE|3432523|65023:3
6111119268639|22|65024:3|2000225350|Apple|ADD|234534643645|REMOVE|3432523|65023:3
6111119268639|22|65024:3|2000225350|Samsung|ADD|234534643645|REMOVE|3432523|65023:3

and so on ...

I want want json output like this below:

[{
    "ExternalId": "6111119268639",
    "ExternalIdType": "22",
    "RPPI": "65024:3",
    "NewPrimaryOfferId": "2000225350",
    "Samsung": [{
            "Action": "ADD",
            "NewSecondaryOfferId": "234534643645"
        },
        {
            "Action": "REMOVE",
            "SecondaryProductOfferId": "5645657",
            "RemoveSecondaryProductInstance": "65067:3"
        }
    ],
    "Apple": [
    {
            "Action": "ADD",
            "NewComponentOfferId": "234534643645"
        },
        {
            "Action": "REMOVE",
            "ComponentOfferId": "3432523",
            "RemoveAddOnProductInstance": "65023:3"
        }
    ]
}, 
{
    "ExternalId": "6111119268639",
    "ExternalIdType": "22",
    "RPPI": "65024:3",
    "NewPrimaryOfferId": "2000225350",
    "Apple": [{
            "Action": "ADD",
            "NewComponentOfferId": "234534643645"
        },
        {
            "Action": "REMOVE",
            "ComponentOfferId": "3432523",
            "RemoveAddOnProductInstance": "65023:3"
        }
    ]
}, 
{
    "ExternalId": "6111119268639",
    "ExternalIdType": "22",
    "RPPI": "65024:3",
    "NewPrimaryOfferId": "2000225350",
    "Apple": [{
            "Action": "Samsung",
            "NewComponentOfferId": "234534643645"
        },
        {
            "Action": "REMOVE",
            "ComponentOfferId": "3432523",
            "RemoveAddOnProductInstance": "65023:3"
        }
    ]
}
]

Here ExternalId,ExternalIdType,RPPI,NewPrimaryOfferId are constant and will be there in every line.But Samsung and Apple can vary accordingly means there could be only 'Samsung' in one line or there could be only 'Apple' in one line or there could be both as shown in sample text.

I have written a Jq command for this like below:

jq -Rn '[inputs / "|" | [[
  
  ["ExternalId"],["ExternalIdType"],["RPPI"],["NewPrimaryOfferId"],
  (("Samsung", "Apple") as $p |
    [$p, 0]   (["Action"], ["NewSecondaryOfferId"]),
    [$p, 1]   (["Action"], ["SecondaryProductOfferId"], ["RemoveSecondaryProductInstance"])
    )

],.] | transpose | reduce .[] as $k ({}; setpath($k[0];$k[1]))]' data.txt

But seems like it is not giving me the desired output I want.Please suggest how can I write the jq command for this using if-else condition for products or any shell script to get the desired json output.Thanks in advance!

CodePudding user response:

This seems to work on your test data:

jq -nR '
   def offer:
     . as $data |
     [[], 0] | until([$data[.[1]]] | inside(["ADD", "REMOVE"]) | not;
       if $data[.[1]] == "ADD" then
        [ .[0]   [{ Action: "ADD", NewComponentOfferId: $data[.[1]   1] }], .[1]   2 ]
       else
        [ .[0]   [{ Action: "REMOVE", ComponentOfferId: $data[.[1]   1], 
          RemoveAddOnProductInstance: $data[.[1]   2] }], .[1]   3 ]
       end);

   def build:
       (. / "|") as $data | ($data | length) as $len |
       [ { ExternalId: $data[0], ExternalIdType: $data[1], RPPI: $data[2],
         NewPrimaryOfferId: $data[3] }, 4 ] |
       until(.[1] >= $len;
             ($data[.[1] 1:] | offer) as $off |
             [ .[0]   { ($data[.[1]]): $off[0] }, .[1]   1   $off[1] ]) |
      .[0];

  [ inputs | build ]' data.txt

CodePudding user response:

Another approach:

jq -Rn '
  [
    inputs / "|" | reduce (.[4:] | while(. != [];.[6:])) as $prod (
      .[:4] | with_entries(.key |= ["ExternalId","ExternalIdType","RPPI","NewPrimaryOfferId"][.]);
      .[$prod[0]] = [
        {Action:"ADD", NewComponentOfferId:$prod[2]},
        {Action:"REMOVE", ComponentOfferId:$prod[4], RemoveAddOnProductInstance:$prod[5]}
      ]
    )
  ]
' data.txt

Demo

  • Related