如何将我的 Bash 脚本输出转换为 JSON 并将其保存为“.json”文件?

如何将我的 Bash 脚本输出转换为 JSON 并将其保存为“.json”文件?

这是我的脚本:

获取系统信息

#!/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`

我想像这样显示我的输出:

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

答案1

只需printf将输出格式化为 JSON即可

首先,您的代码的这一部分有一个非常明显的拼写错误:

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

请注意,没有结束的直引号:"。我在下面进行的重写中修复了它:

但更重要的是,做这样的事情(使用printf正如这个 StackOverflow 答案中所建议的那样. 在 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"

我得到的输出是这样的:

{"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 "}

如果你有jq安装后,您可以将 shell 脚本的输出通过管道传输到,以jq将输出“漂亮地打印”为某种人类可读的格式。假设您的脚本名为my_script.sh,只需将其通过管道传输到,jq如下所示:

./my_script.sh | jq

输出结果如下:

{
  "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 "
}

答案2

以下程序可以输出json

瘦身

lshw -json

智能工具v7 +:

smartctl --json --all /dev/sda

lsblk

lsblk --json

利西普

lsipc --json

磁盘管理

sfdisk --json

答案3

如果您运行的输出格式始终相同,则可以执行类似下面的操作。要使用 awk,只需将 $Number 更改为要提取的输出中的任何列。“Hello World”$1 等于 Hello $2 等于 world。由于您需要使用“”符号(这是 bash 中的本机函数),因此您可能需要执行类似 '"' 或 "'"'" 的操作来打印一个。下面的代码如果不进行调整将无法工作,但我相信您可以从我所说的内容和 awk 手册页中找出答案。

echo '}' >> file.temp
command | awk '{ print "text/symbols" $1, "text/symbols" $2 "text/symbols" }' >> file.temp
command | awk '{ print "text/symbols" $1, "text/symbols" $2 "text/symbols" }' >> file.temp
command | awk '{ print "text/symbols" $1, "text/symbols" $2 "text/symbols" }' >> file.temp
command | awk '{ print "text/symbols" $1, "text/symbols" $2 "text/symbols" }' >> file.temp

echo '}' >> file.temp

答案4

jq您的系统上安装了“ ”吗?

如果是,请使用它来格式化输出。它确实比任何解决方案都更能输出有效的 JSON。

#! /bin/bash

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

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

# This is a JSON format string, not a bash string
# shellcheck disable=SC2016
declare -r JSON_FORMAT='{
    "manufacturer": $manufacturer,
    "product_name": $product_name,
    "version": $version,
    "serial_number": $serial_number,
    "hostname": $hostname,
    "operating_system": $hostname,
    "architecture": $architecture,
    "processor_name": $processor_name,
    "memory": $memory,
    "hdd_model": $hdd_model,
    "system_main_ip": $system_main_ip
    }'

declare -r JSON_CONTENT=$(jq \
        --null-input \
        --arg manufacturer     "${manufacturer}"     \
        --arg product_name     "${product_name}"     \
        --arg version          "${version}"          \
        --arg serial_number    "${serial_number}"    \
        --arg hostname         "${hostname}"         \
        --arg operating_system "${operating_system}" \
        --arg architecture     "${architecture}"     \
        --arg processor_name   "${processor_name}"   \
        --arg memory           "${memory}"           \
        --arg hdd_model        "${hdd_model}"        \
        --arg system_main_ip   "${system_main_ip}"   \
        "${JSON_FORMAT}" \
    )

printf "%s" "${JSON_CONTENT}"

相关内容