I have to create a simple bash script that converts .txt outputs to JSON code. The pattern is as follows:
[ Example ], 1..3 tests
-----------------------------------------------------------------------------------
not ok 1 text1 (text1), 5ms
ok 2 text2 (text2, issues), 2ms
ok 3 text3 (text3, issues), 15ms
-----------------------------------------------------------------------------------
2 (of 3) tests passed, 1 tests failed, rated as 66.66%, spent 22ms
This will have to be converted to the following JSON (as an example):
{
"testName": " Example ",
"tests": [
{
"name": "",
"status": false,
"duration": ""
},
{
"name": "",
"status": true,
"duration": ""
}
],
"summary": {
"success": ,
"failed": ,
"rating": ,
"duration": ""
}
}
I managed to almost complete the requirements, the test name is taken out correctly from the txt and also the summary results are taken correctly, but the only problem is with the tests part which does not work at all, not even the variables set upfor that are recognosed.
My code is:
#!/bin/bash
###################PREREQUISITES#####################
# Check if the output file is provided as an argument (I chose to do so to be able tospecify location)
if [ $# -eq 0 ]; then
echo "Usage: $0 <output_json_file>"
exit 1
fi
input_file="example_file.txt" #File that is being used as source to convert FROM
output_file=$1 #Output file location as an argument to convert TO
# Check if the input file exists
if [ ! -f "$input_file" ]; then
echo "Input file '$input_file' not found."
exit 1
fi
###################CODE#####################
#Setting up a pattern variable for the lines with the values that we need as JSON variables:
pattern='"^(ok|not ok)[[:space:]]{2,}([0-9])[[:space:]]{2,}(.+),[[:space:]]+([0-9]{1,3}ms)$"'
# Read the input_file line by line:
while IFS= read -r line; do
# Extract the test_Name from the first line -> IT WORKS
if [[ "$line" =~ \[([^\]]+)\] ]]; then
testName="${BASH_REMATCH[1]}"
# Extract values using BASH_REMATCH on the pattern variable -> IT DOES NOT WORK
elif [[ "$line" =~ $pattern ]]; then
status="${BASH_REMATCH[1]}"
status_code="${BASH_REMATCH[2]}"
name="${BASH_REMATCH[3]}"
duration="${BASH_REMATCH[4]}"
break
elif [[ "$line" =~ ^([0-9]+)\ \(of\ [0-9]+\)\ tests\ passed,\ ([0-9]+)\ tests\ failed,\ rated\ as\ ([0-9.]+)%,\ spent\ ([0-9]+)ms$ ]]; then
success="${BASH_REMATCH[1]}"
failed="${BASH_REMATCH[2]}"
rating="${BASH_REMATCH[3]}"
duration="${BASH_REMATCH[4]}ms"
break
fi
done < $input_file
# Construct the JSON output
output_json="{
\"testName\": \"$testName\",
\"tests\": [
${tests[@]}
],
\"summary\": {
\"success\": $success,
\"failed\": $failed,
\"rating\": $rating,
\"duration\": \"$duration\"
}
}"
# Write the JSON output to the output file
echo "$output_json" > "$output_file"
echo "Conversion completed. JSON output written to $output_file"
As for now the status is that either only the Name works, so the TESTS and SUMMARY section is not filled in to the JSON file, or (if modified with removing tests) the NAME and SUMMARY works but TESTS dont.
Example txt:
[ Samples ], 1..7 tests
---------
not ok 1 expecting cmd finishes successfully (bash way), 5ms
not ok 2 expecting cmd finishes successfully (the same as above, bash way), 20ms
ok 3 expecting cmd fails (same as above, bash way), 20ms
ok 4 expecting cmd prints exact value (bash way), 10ms
ok 5 expecting cmd prints exact value (the same as above, bash way), 10ms
ok 6 expecting cmd prints some message (bash way), 15ms
ok 7 expecting cmd prints some message (the same as above, bash way), 15ms
---------
5 (of 7) tests passed, 2 tests failed, rated as 71.43%, spent 95ms
What am I doing wrong? Is there something I am doing fundamentally wrong with this?
Thanks for the advice in advance!
pattern, they don't belong there. The final result refers to atestarray that hasn't been assigned at all; it looks like the[[ "$line" =~ $pattern ]]section should add to that array, and notbreak. Also, expanding a bash array inside a string will not produce a valid JSON array. For this and many similar reasons, you shouldn't use bash to create JSON directly, you should use something likejqto JSONify the data (see this and this).