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