With jq, we can easily convert between JSON and JSON lines.

JSON -> JSON Lines

$ printf '[{"A":"B"},{"C":"D"}]' | jq -c .[]
{"A":"B"}
{"C":"D"}

Note: -c (--compact-output) option is important to put each JSON object on a single line.

JSON Lines -> JSON

$ printf '{"A":"B"}\n{"C":"D"}' | jq -s
[
  {
    "A": "B"
  },
  {
    "C": "D"
  }
]

-s (--slurp) option wraps the whole input into a large array.

Add -c (--compact-output) option to make the whole array on a single line.

$ printf '{"A":"B"}\n{"C":"D"}' | jq -cs
[{"A":"B"},{"C":"D"}]

Deal with JSON lines mixed with plain text

If you're dealing with programs which output JSON lines along with plain text, you can extract only the JSON lines with:

cat mixed.jsonl | jq -Rc 'fromjson?'

-R (--raw-input) parses each line of text as a string;
fromjson converts the string back into JSON object;
? tries to do the conversion and ignores those don't convert;
-c (--compact-output) puts each JSON object on a single line.

Example

Input:

calling cmd
Listening for transport dt_socket at address: 8787
{"@timestamp":"2020-06-09T02:46:14.635Z","@version":"1","message":"\nMetrics for local node (to disable set 'metricsLogFrequency' to 0)\n    ^-- Node [id=f8807a97, uptime=00:21:00.130]\n    ^-- H/N/C [hosts=5, nodes=5, CPUs=34]\n    ^-- CPU [cur=0.4%, avg=15.09%, GC=0%]\n    ^-- PageMemory [pages=2256]\n    ^-- Heap [used=3304MB, free=77.31%, comm=9370MB]\n    ^-- Non heap [used=101MB, free=96.95%, comm=102MB]\n    ^-- Public thread pool [active=0, idle=0, qSize=0]\n    ^-- System thread pool [active=0, idle=6, qSize=0]\n    ^-- Outbound messages queue [size=0]","thread_name":"grid-timeout-worker-#23","level":"INFO","level_value":20000}

Command:

cat input | jq -Rrc 'fromjson?|.message'

Output:


Metrics for local node (to disable set 'metricsLogFrequency' to 0)
    ^-- Node [id=f8807a97, uptime=00:21:00.130]
    ^-- H/N/C [hosts=5, nodes=5, CPUs=34]
    ^-- CPU [cur=0.4%, avg=15.09%, GC=0%]
    ^-- PageMemory [pages=2256]
    ^-- Heap [used=3304MB, free=77.31%, comm=9370MB]
    ^-- Non heap [used=101MB, free=96.95%, comm=102MB]
    ^-- Public thread pool [active=0, idle=0, qSize=0]
    ^-- System thread pool [active=0, idle=6, qSize=0]
    ^-- Outbound messages queue [size=0]

Note that -r (--raw-output) parses escape sequences within the string.