How can I convert my Bash script output to JSON and save it as “.json” file?

Here is my script:

Get System info

#!/bin/bash

readarray -t array <<< "$(df -h)"

var=$(echo "${array[1]}"| grep -aob '%' | grep -oE '[0-9]+')

echo "${array[3]:$var-3:4}

echo -e "Manufacturer:\t"`cat /sys/class/dmi/id/chassis_vendor`

echo -e "Product Name:\t"`cat /sys/class/dmi/id/product_name`

echo -e "Version:\t"`cat /sys/class/dmi/id/bios_version`

echo -e "Serial Number:\t"`cat /sys/class/dmi/id/product_serial`

echo -e "PC Name:\t"`hostname`

echo -e "Operating System:\t"`hostnamectl | grep "Operating System" | cut -d ' ' -f5-`

echo -e "Architecture:\t"`arch`

echo -e "Processor Name:\t"`awk -F':' '/^model name/ {print $2}' /proc/cpuinfo | uniq | sed -e 
              's/^[ \t]*//'`

echo -e "Memory:\t" `dmidecode -t 17 | grep "Size.*MB" | awk '{s+=$2} END {print s / 1024"GB"}'`

echo -e "HDD Model:\t" `cat /sys/block/sda/device/model`

echo -e "System Main IP:\t"`hostname -I`

I want to display my output like this:

(
    {
    
        "Manufacturer":"Lenovo",
        "Product Name":"Thinkpad",
        "Version":"T590",
        "Serial Number":"1234567890"
    }
)

Solution 1:

Simply use printf to format the output into JSON

First, you have a very blatant typo in this part of your code right here:

echo "${array[3]:$var-3:4}

Note there is no closing straight quote: ". Fixed it in the rewrite I did below:

But more to the point, doing something like this (using printf) as suggested in this StackOverflow answer. Tested and works in CentOS 7.

#!/bin/bash

readarray -t array <<< "$(df -h)";
var=$(echo "${array[1]}"| grep -aob '%' | grep -oE '[0-9]+');
df_output="${array[3]:$var-3:4}";

manufacturer=$(cat /sys/class/dmi/id/chassis_vendor);
product_name=$(cat /sys/class/dmi/id/product_name);
version=$(cat /sys/class/dmi/id/bios_version);
serial_number=$(cat /sys/class/dmi/id/product_serial);
hostname=$(hostname);
operating_system=$(hostnamectl | grep "Operating System" | cut -d ' ' -f5-);
architecture=$(arch);
processor_name=$(awk -F':' '/^model name/ {print $2}' /proc/cpuinfo | uniq | sed -e 's/^[ \t]*//');
memory$(dmidecode -t 17 | grep "Size.*MB" | awk '{s+=$2} END {print s / 1024"GB"}');
hdd_model=$(cat /sys/block/sda/device/model);
system_main_ip=$(hostname -I);

printf '{"manufacturer":"%s","product_name":"%s","version":"%s","serial_number":"%s","hostname":"%s","operating_system":"%s","architecture":"%s","processor_name":"%s","memory":"%s","hdd_model":"%s","system_main_ip":"%s"}' "$manufacturer" "$product_name" "$version" "$serial_number" "$hostname" "$operating_system" "$architecture" "$processor_name" "$memory" "$hdd_model" "$system_main_ip"

The output I get is this:

{"manufacturer":"Oracle Corporation","product_name":"VirtualBox","version":"VirtualBox","serial_number":"","hostname":"sandbox-centos-7","operating_system":"CentOS Linux 7 (Core)","architecture":"x86_64","processor_name":"Intel(R) Core(TM) i5-1030NG7 CPU @ 1.10GHz","memory":"","hdd_model":"VBOX HARDDISK   ","system_main_ip":"10.0.2.15 192.168.56.20 "}

And if you have jq installed, you can pipe the output of the shell script to jq to “pretty print” the output into some human readable format. Like let’s say your script is named my_script.sh, just pipe it to jq like this:

./my_script.sh | jq

And the output would look like this:

{
  "manufacturer": "Oracle Corporation",
  "product_name": "VirtualBox",
  "version": "VirtualBox",
  "serial_number": "",
  "hostname": "sandbox-centos-7",
  "operating_system": "CentOS Linux 7 (Core)",
  "architecture": "x86_64",
  "processor_name": "Intel(R) Core(TM) i5-1030NG7 CPU @ 1.10GHz",
  "memory": "",
  "hdd_model": "VBOX HARDDISK   ",
  "system_main_ip": "10.0.2.15 192.168.56.20 "
}