74

I am trying to curl some URL which returns a json file, then I want to parse hosts from it and create a comma separated string.

I have the first part working

curl -s -u "admin:admin" -H "X-Requested-By: ambari" "https://hbasecluster.net/api/v1/clusters/mycluster/services/ZOOKEEPER/components/ZOOKEEPER_SERVER" | jq -r '.host_components[].HostRoles.host_name'

which returns

zk0-mycluster.net
zk1-mycluster.net
zk2-mycluster.net

Now I want to join these into one string like

zk0-mycluster.net,zk1-mycluster.net,zk2-mycluster.net
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
rp346
  • 1,389

4 Answers4

147

Do it in jq, but see @Kusalananda's answer first

jq -r '.host_components[].HostRoles.host_name | join(",")'

No, that's wrong. This is what you need:

jq -r '.host_components | map(.HostRoles.host_name) | join(",")'

Demo:

jq -r '.host_components | map(.HostRoles.host_name) | join(",")' <<DATA
{"host_components":[
  {"HostRoles":{"host_name":"one"}},
  {"HostRoles":{"host_name":"two"}},
  {"HostRoles":{"host_name":"three"}}
]}
DATA

outputs

one,two,three
glenn jackman
  • 85,964
  • 7
    just as an alternative, should also work: jq -r '[.host_components[].HostRoles.host_name] | join(",")' – webwurst Aug 13 '19 at 15:40
  • @webwurst just tried, it's not working in case if you're selecting multiple columns/keys. For example: jq -r '[.host_components[].HostRoles.some_other_value, .host_components[].HostRoles.host_name] | join(",")]' – М.Б. Aug 14 '19 at 16:41
34

paste is the best tool to do this job:

your_command | paste -sd, -
cuonglm
  • 153,898
17

If what you want is CSV-formatted output from your JSON document, then you may use the @csv operator in jq.

somecommand | jq -r '[ .host_components[].HostRoles.host_name ] | @csv'

This uses the same expression that you're using in the question to pull out the data that you want, but it puts all the host names into an array. The array is then passed through @csv which makes sure that that the data is properly quoted for CSV output.

You would expect to get the following output from this:

"zk0-mycluster.net","zk1-mycluster.net","zk2-mycluster.net"

Any commas, double quotes, or newlines embedded in the values would be properly quoted as expected in a CSV-formatted file.

Kusalananda
  • 333,661
4

If you want to use awk, just print with no newline:

    <your command> | awk 'NR > 1 { printf(",") } {printf "%s",$0}'
Echoes_86
  • 752