0

I have a json file with this content:

[
  {
    "id": "one",
    "msg": [
      "test"
    ],
    "FilePath": [
      "JsonSerializer.cs",
      "ChatClient.cs",
      "MiniJSON.cs"
    ],
    "line": [
      358,
      1241,
      382
    ]
  },
  {
    "id": "two",
    "msg": [
      "secondtest"
    ],
    "FilePath": [
      "Utilities.cs",
      "PhotonPing.cs"
    ],
    "line": [
      88,
      36
    ]
  }
]

I want the output where as you can see the value combine into one :

one
[
  "test"
]
[
  "JsonSerializer.cs",358
  "ChatClient.cs",1241
  "MiniJSON.cs",382
]

two
[
  "secondtest"
]
[
  "Utilities.cs",88
  "PhotonPing.cs",36
]

I have tried this cat stack.json |jq -r '.[]|.id,.msg,.FilePath,.line' which gave output as

  one
    [
      "test"
    ]
    [
      "JsonSerializer.cs",
      "ChatClient.cs",
      "MiniJSON.cs"
    ]
    [
      358,
      1241,
      382
    ]
    two
    [
      "secondtest"
    ]
    [
      "Utilities.cs",
      "PhotonPing.cs"
    ]
    [
      88,
      36
    ]

Kindly help me resolve this, I have tried a lot to debug this but unable to get through. Also, the Filepath and line would always be similar for each . For example if FilePath has 3, line would also have 3 values.

1
  • The expected output as shown is neither valid JSON nor an interleaved stream of valid JSON texts and raw strings. Please clarify what output would be acceptable. Commented Sep 6, 2022 at 18:49

2 Answers 2

1

You're looking for transpose.

.[] | .id, .msg, ([.FilePath, .line] | transpose | add), ""

Online demo

Sign up to request clarification or add additional context in comments.

7 Comments

The transpose|add pipeline is so elegant. I came up with the clunky (. as $o | reduce range(.FilePath | length) as $i ([]; . + [$o.FilePath[$i], $o.line[$i]]))
@glennjackman Cool. I saw your exercism profile, have you tried solving the satellite challenge using JQ? That's way cooler
heh. not yet...
there, it's much better now.
|
0
<stack.json jq -r '.[] | .id, .msg, ([.FilePath, .line]|transpose|add)'

gives the output as required by you.

transpose turns [[1,2,3],[4,5,6]] into [[1,4],[2,5],[3,6]] and add collects all array elements into a single array.

If you are looking to have file path and line number in a single line, I suggest formatting them as string, separated by colon:

.[] | .id, .msg, ([.FilePath, .line]|transpose|map(join(":")))

3 Comments

Your program produces output that includes commas that the "expected output" does not have.
@peak thanks, a valid point. Let's wait for the author to clarify if a typo in the requirements or if an invalid JSON output is indeed expected.
@knittl Many thanks for your ans. That file was originally a json one which after some data manipulation resulted into the one i posted (which now becomes a non-json format) . As suggested , transpose works for my problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.