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".
CodePudding user response:
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
CodePudding user response:
Here is how to do it with a simple bash-script:
#!/bin/bash
echo "{"
echo " \"tools\": {"
while IFS=: read -r name value
do
echo " $comma\"$name\": \"$value\""
comma=","
done < tools.txt
echo " }"
echo "}"
... just to demonstrate the principle.
CodePudding user response:
Using your already created tools.json file, you can try this sed
$ sed '/tools/{n;s!.*!tac tools.txt|sed "s/^/\t/;2,$ s/$/\\",/;s/$/\\"/"|tac!e};/[a-z]/s/\t\([^:]*\):/\t"\1" : "/g' tools.json
{
"tools": {
"docker" : "19.03.8",
"go" : "1.18",
"kubernetes" : "1.20"
}
}
CodePudding user response:
The requirement is quite simple that you don't need loop or jq, you can use only commands and pipes:
λ 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"}}
Explanation
Use tr xargs printf and paste to generate the JSON tools body part:
tr : ' ' < tools.txt |
xargs printf '"%s":"%s"\n' |
paste -s -d , -
"docker":"19.03.8","go":"1.18","kubernetes":"1.20"
Prepend '{"tools":{' and append '}}\n' by printf:
printf '{"tools":{'$(YOUR COMMAND)'}}\n'
