29

I have a command that I run and it gives an output like below:

{ "endpointApplications": { "App_Name": { "connectionState": "Disconnected", "connectionTime": "No connection was established", "linkAttributes": { "ackSettings": { "dataAckEnabled": "true", "dataAckTimeout": "5000", "dataNakRetryLimit": "0", "retransmitDelay": "500" }, "keepAliveSettings": { "keepAliveAckTimeout": "5000", "keepAliveInterval": "30000" }, "logTraffic": "false", "port": "9999", "role": "server" }, "protocol": "snmp" } }, "queueStats": {} } 

I would need the output to be in one line like below:

{"endpointApplications": {"app_name": {"connectionState": "Disconnected","connectionTime": "No connection was established","linkAttributes": {"ackSettings":{"dataAckEnabled": "true","dataAckTimeout": "5000","dataNakRetryLimit": "0","retransmitDelay": "500"},"keepAliveSettings":{"keepAliveAckTimeout": "5000","keepAliveInterval": "30000"},"logTraffic": "false","port": "9999","role": "server"},"protocol": "snmp"}},"queueStats":{}} 

I tried using awk and sed combining different parameters but I can't get to work without losing the JSON format.

1
  • 2
    Consider using jq for whatever you appear to be trying to do to each resulting line :) Commented Sep 22, 2016 at 20:31

2 Answers 2

47

You should use jq for stuff like that:

jq -c . input.txt 

An alternative quick a dirty solution would be to use sed & tr:

sed -e 's/^ *//' < input.txt | tr -d '\n' 

although I would recommend using jq which is designed for manipulating JSON. jq is like sed for JSON. Manipulating JSON textually with sed/awk/etc is not guaranteed to produce semantically equivalent JSON.

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

2 Comments

You can obtain jq under a Debian-flavored Linux (such as Ubuntu) with a simple sudo apt-get install jq
Alternative solution worked for me, because I managed json data from mongodb, that contains special datatypes
18

jq or any other json aware tool is best suited for json file manipulation.However here is awk based solution.

awk -v RS= '{$1=$1}1' input.json { "endpointApplications": { "App_Name": { "connectionState": "Disconnected", "connectionTime": "No connection was established", "linkAttributes": { "ackSettings": { "dataAckEnabled": "true", "dataAckTimeout": "5000", "dataNakRetryLimit": "0", "retransmitDelay": "500" }, "keepAliveSettings": { "keepAliveAckTimeout": "5000", "keepAliveInterval": "30000" }, "logTraffic": "false", "port": "9999", "role": "server" }, "protocol": "snmp" } }, "queueStats": {} } 

Note: This solution is mainly for the legacy systems not having tools like jq and have no chance to get them installed due to some reasons.

3 Comments

can you please help me further by explaining awk action part {$1=$1}1 a bit. I wrote my own something like awk -v ORS= '{ print $0 } END { printf "\n" }' but yours is far better!!
{$1=$1}1 is a famous construct in awk world. This is done to force/fake awk to reconstruct the record using the value of RS we passed. Without the reconstruction of the record the value we passed for RS won't show up in the results. Btw you can use anything for reconstruction of the record like $8=$8. The last 1, is to force the conditions to be true for printing.
Also, to make more sense , in awk by default a record is equal to a line. Eg speerated by new line.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.