Search code examples
jsonbashnewlinejqoutput-formatting

How to get newline on every iteration in jq


I have the following file

[
  {
    "id": 1,
    "name": "Arthur",
    "age": "21"
  },
  {
    "id": 2,
    "name": "Richard",
    "age": "32"
  }
]

To display login and id together, I am using the following command

$ jq '.[] | .name' test
"Arthur"
"Richard"

But when I put it in a shell script and try to assign it to a variable then the whole output is displayed on a single line like below

#!/bin/bash

names=$(jq '.[] | .name' test)
echo $names

$ ./script.sh
"Arthur" "Richard"

I want to break at every iteration similar to how it works on the command line.


Solution

  • Couple of issues in the information you have provided. The jq filter .[] | .login, .id will not produce the output as you claimed on jq-1.5. For your original JSON

    {  
       "login":"dmaxfield",
       "id":7449977
    }
    {  
       "login":"stackfield",
       "id":2342323
    }
    

    It will produce four lines of output as,

    jq -r '.login, .id' < json
    dmaxfield
    7449977
    stackfield
    2342323
    

    If you are interested in storing them side by side, you need to do variable interpolation as

    jq -r '"\(.login), \(.id)"' < json
    dmaxfield, 7449977
    stackfield, 2342323
    

    And if you feel your output stored in a variable is not working. It is probably because of lack of double-quotes when you tried to print the variable in the shell.

    jqOutput=$(jq -r '"\(.login), \(.id)"' < json)
    printf "%s\n" "$jqOutput"
    dmaxfield, 7449977
    stackfield, 2342323
    

    This way the embedded new lines in the command output are not swallowed by the shell.


    For you updated JSON (totally new one compared to old one), all you need to do is

    jqOutput=$(jq -r '.[] | .name' < json)
    printf "%s\n" "$jqOutput"
    Arthur
    Richard