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'