I am writing a small bash script and I am stuck. I have a text file with some information and I stored the contents of that file in a bash variable.
tools=$(cat tools.txt)
My tools.txt
file looks like this:
docker:19.03.8
go:1.18
kubernetes:1.20
And so on.
What I want is to dynamically create a JSON file named tools.json
and to populate that file with the content from tools.txt
.
In my tools.json
file I have the following structure:
{
"tools": {
}
}
And this should be the final structure.
{
"tools": {
"name" : "version"
}
}
So the expected output is:
{
"tools": {
"docker" : "19.03.8",
"go" : "1.18",
"kubernetes" : "1.20"
}
}
I don’t know how to loop through the $tools
variable or tools.txt
file in such a way that on each iteration a new line ("docker" : "19.03.8"
) is added to tools.json
file.
I tried something like this
cat <<EOF > ./tools.json
{
"tools": {
for tool in $tools
do
"name" : "version",
done
}
}
EOF
Of course, it doesn’t work. The idea is that instead of "name" : "version"
in a loop to use something like "$name" : "$version"
.
Advertisement
Answer
You can use the tool “jq” for that.
https://stedolan.github.io/jq/manual/
I would do something like this:
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
A better solution would be:
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