如何使用来自 bash 变量的数据填充 json 文件

How to populate json file with data from bash variable

我正在编写一个小 bash 脚本,但我被卡住了。我有一个包含一些信息的文本文件,我将该文件的内容存储在 bash 变量中。

tools=$(cat tools.txt)

我的 tools.txt 文件如下所示:

docker:19.03.8
go:1.18
kubernetes:1.20

以此类推

我想要的是动态创建一个名为 tools.json 的 JSON 文件,并用 tools.txt.

中的内容填充该文件

在我的 tools.json 文件中,我有以下结构:

{
    "tools": {

     }
}

这应该是最终结构。

{
    "tools": {
         "name" : "version"
     }
}

所以预期的输出是:

{
    "tools": {
         "docker" : "19.03.8",
         "go" : "1.18",
         "kubernetes" : "1.20"
     }
}

我不知道如何循环遍历 $tools 变量或 tools.txt 文件,以便在每次迭代时将新行 ("docker" : "19.03.8") 添加到 tools.json 文件.

我试过这样的东西


cat <<EOF > ./tools.json
{
   "tools": {
        for tool in $tools
        do
                "name" : "version",
        done
   }
}
EOF

当然不行。这个想法是,而不是 "name" : "version" 在循环中使用像 "$name" : "$version".

这样的东西

您可以为此使用工具“jq”。

https://stedolan.github.io/jq/manual/

我会这样做:

cat > tools.json << EOF
{
    "tools": {

    }
}
EOF

for item in "${tools[@]}"; do
    tool=$(echo "$item" | cut -d ":" -f1)
    version=$(echo "$item" | cut -d ":" -f2)
    old_content=$(cat tools.json)

    echo "$old_content" | jq \
        --arg TOOL "$tool" \
        --arg VERSION "$version" \
        '.tools += { ($TOOL) : ($VERSION) }' \
        > tools.json
done

更好的解决方案是:

while IFS=":" read -r tool version; do
    old_content=$(cat tools.json)
    echo "$old_content" | jq \
        --arg TOOL "$tool" \
        --arg VERSION "$version" \
        '.tools += { ($TOOL) : ($VERSION) }' \
        > tools.json
done < tools.txt

这里是如何使用简单的 bash-script:

#!/bin/bash

echo "{"
echo "    \"tools\": {"

while IFS=: read -r name value
do
    echo "        $comma\"$name\": \"$value\""
    comma=","
done < tools.txt

echo "    }"
echo "}"

...只是为了演示原理。

使用您已经创建的 tools.json 文件,您可以试试这个 sed

$ sed '/tools/{n;s!.*!tac tools.txt|sed "s/^/\t/;2,$ s/$/\",/;s/$/\"/"|tac!e};/[a-z]/s/\t\([^:]*\):/\t"" : "/g' tools.json
{
    "tools": {
        "docker" : "19.03.8",
        "go" : "1.18",
        "kubernetes" : "1.20"
     }
}

要求很简单,不需要loopjq,只用命令和管道即可:

λ cat tools.txt 
docker:19.03.8
go:1.18
kubernetes:1.20
printf '{"tools":{'$(
  tr : ' ' <tools.txt |
    xargs printf '"%s":"%s"\n' |
    paste -s -d , -
)'}}\n'
{"tools":{"docker":"19.03.8","go":"1.18","kubernetes":"1.20"}}

说明

使用trxargsprintfpaste生成JSONtools正文部分:

tr : ' ' < tools.txt |
  xargs printf '"%s":"%s"\n' |
  paste -s -d , -
"docker":"19.03.8","go":"1.18","kubernetes":"1.20"

通过 printf:

添加 '{"tools":{' 和附加 '}}\n'
printf '{"tools":{'$(YOUR COMMAND)'}}\n'