0

I have an data which i am trying to fetch various method and the result is

[
"created:Alpha;DateCreated:12/12/2022;TicketNo:XXXX_XXX;ProductName:websphere;OStype:Linux"
]

I want to fetch the ostype as Linux from the above i tried to use JQ and no luck. any suggestions

Thanks

Raj

1
  • What did you try with jq? It might be easier to correct something than to solve the whole problem for you. And you get to really show your research ;). Commented Mar 29, 2023 at 19:55

3 Answers 3

1

Here's another way to wrangle your input with pure jq:

$ jq '.[] / ";" | reduce .[] as $item ({}; . + ($item / ":" | {(.[0]): (.[1])}))' file
{
  "created": "Alpha",
  "DateCreated": "12/12/2022",
  "TicketNo": "XXXX_XXX",
  "ProductName": "websphere",
  "OStype": "Linux"
}

You can then extract the desired field directly:

jq -r '.[] / ";" | reduce .[] as $item ({}; . + ($item / ":" | {(.[0]): (.[1])})) | .OStype' file
Linux
2
  • It's not clear from the question, but since their top-level thing is an array, I'm assuming they may have multiples of these strings in the array (why else have an array?). I opted for always returning the first string's OStype. You are returning all of them. Not that there's anything wrong, mind. It's just a difference in assumptions in what they have and what they want.
    – Kusalananda
    Commented Mar 29, 2023 at 20:24
  • Looks like brainfuck language ^^ Not sure about maintainability =) Commented Mar 29, 2023 at 20:32
1

It would be so much easier if your data looked like this:

[
  {
    "created": "Alpha",
    "DateCreated": "12/12/2022",
    "TicketNo": "XXXX_XXX",
    "ProductName": "websphere",
    "OStype": "Linux"
  }
]

From this, we could pick out the value of the OStype key in the first element of the top-level array using jq as so:

jq -r 'first.OStype'

So how do we get your data into that more manageable form? Well, we start by splitting the strings in your array on semi-colons, and then again on colons:

$ jq -r 'map(split(";"))' file
[
  [
    "created:Alpha",
    "DateCreated:12/12/2022",
    "TicketNo:XXXX_XXX",
    "ProductName:websphere",
    "OStype:Linux"
  ]
]
$ jq 'map(split(";")|map(split(":")))' file
[
  [
    [
      "created",
      "Alpha"
    ],
    [
      "DateCreated",
      "12/12/2022"
    ],
    [
      "TicketNo",
      "XXXX_XXX"
    ],
    [
      "ProductName",
      "websphere"
    ],
    [
      "OStype",
      "Linux"
    ]
  ]
]

We then turn each of the sub-sub arrays into key-value pairs via the from_entries function (?) in jq after designating the first element as the key and the second element as the value, and see...

$ jq 'map(split(";")|map(split(":")) | map({key:.[0],value:.[1]})|from_entries)' file
[
  {
    "created": "Alpha",
    "DateCreated": "12/12/2022",
    "TicketNo": "XXXX_XXX",
    "ProductName": "websphere",
    "OStype": "Linux"
  }
]

Then either pipe that to the first jq command in the answer here or incorporate that into what we already have:

$ jq -r 'map(split(";")|map(split(":")) | map({key:.[0],value:.[1]})|from_entries) | first.OStype' file
Linux

Right, so that's useful if we wanted to convert all of your data into something more useful, possibly for other things than to pull a single value out of it. But what if we want to reach in and grab that Linux string without converting everything into nice-looking JSON objects? We can do this easily enough with the list of lists of lists above, with a select() call. Just pick out the second element of the sub-sub array whose first element is the string OSType:

$ jq -r 'map(split(";")|map(split(":"))) | first[] | select(.[0] == "OStype")[1]' file
Linux

Or, if you have full control over the ordering of these strings and know the value you're looking for is the last value in that string of key-value pairs, meaning we don't have to go looking for it in all sub-sub arrays:

$ jq -r 'map(split(";")|map(split(":"))) | first[-1][1]' file
Linux

Or, if you want to use regular expressions, just capture the string after OStype: in your string:

$ jq -r 'map(capture("OStype:(?<OStype>[^;]+)")) | first.OStype' file
Linux

Anyway, that's if you want to do it with jq.

0

With just Perl:

$ perl -MJSON::XS -MFile::Slurp -E '
    my $json = read_file("json");
    $json = decode_json $json;
    $_ = $json->[0];
    s/.*OStype://;
    say
'

Return:

Linux

With gron and GNU grep:

$ gron file | grep -oP 'created:.*OStype:\K\w+'
Linux

With gron and Perl:

$ gron file | perl -nE 'say $& if /created:.*OStype:\K\w+/'
Linux

Or with jq and GNU grep:

$ jq '.[]' | grep -oP 'created:.*OStype:\K\w+'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .