Hello there,
есть необходимость (тестовое задание) написать скрипт, который примет как аргумент текстовый файл, а на выходе создаст новый файл на основе старого в JSON формате.
К примеру сам input.txt выглядит так:
[ Asserts Samples ], 1..2 tests
-----------------------------------------------------------------------------------
not ok 1 expecting command finishes successfully (bash way),
7ms
ok 2 expecting command prints some message (the same as above, bats way), 10ms
-----------------------------------------------------------------------------------
1 (of 2) tests passed, 1 tests failed, rated as 50%, spent 17ms
А по итогу должно новый файл должен выглядеть так:
{
"testName": "Asserts Samples",
"tests": [
{
"name": "expecting command finishes successfully (bash way)",
"status": false,
"duration": "7ms"
},
{
"name": "expecting command prints some message (the same as above, bats way)",
"status": true,
"duration": "10ms"
}
],
"summary": {
"success": 1,
"failed": 1,
"rating": 50,
"duration": "17ms"
}
}
Т.е. как видно из примера есть:
- Первая строка, где нас интересует только название в квадратных скобках
- Две разделительные строки, которые никому вообще не сдались
- n-ое количество строк, где важен результат (true/false), самое название (от номер до запятой) и потраченное время.
- Самая последняя строка, где и будет результат (сколько success, сколько failed, rating и общее duration).
И в общем в теории в input.txt может быть и другая инфа (больше тестов, а значит больше строк и другие данные в summary), однако структура одна и та же: название, разделители, тесты, результат.
Считаю себя достойным newbie и поэтому сам пока додумался только до идеи, но не до реализации. Пробовал через jq, однако проще головой удариться о собственный локоть.
Update. По итогу решил таким образом
#!/bin/bash
#create path to redirect output.json to same directory as output.txt
path=$(dirname $1)
#create variables for name line, test lines and result line
firstline=$(cat $1 | head -n +1 | cut -d "[" -f2 | cut -d "]" -f1)
testname=$(echo $firstline)
tests=$(cat $1 | tail -n +3 | head -n -2)
results=$(cat $1 | tail -n1)
#create main JSON variable
json=$(jq -n --arg tn "$testname" '{testname:$tn,tests:[],summary:{}}')
#test's names, status, duration and updating JSON variable
IFS=$'\n'
for i in $tests
do
if [[ $i == not* ]]
then
stat=false
else
stat=true
fi
if [[ $i =~ expecting(.+?)[0-9] ]]
then
var=${BASH_REMATCH[0]}
name=${var%,*}
fi
if [[ $i =~ [0-9]*ms ]]
then
test_duration=${BASH_REMATCH[0]}
fi
json=$(echo $json | jq \
--arg na "$name" \
--arg st "$stat" \
--arg dur "$test_duration" \
'.tests += [{name:$na,status:$st|test("true"),duration:$dur}]')
done
#final success, failed, rating, duration and finishing JSON variable
IFS=$'\n'
for l in $results
do
if [[ $l =~ [0-9]+ ]]
then
success=${BASH_REMATCH[0]}
fi
if [[ $l =~ ,.[0-9]+ ]]
then
v=${BASH_REMATCH[0]}
failed=${v:2}
fi
if [[ $l =~ [0-9]+.[0-9]+% ]] || [[ $l =~ [0-9]+% ]]
then
va=${BASH_REMATCH[0]}
rating=${va%%%}
fi
if [[ $l =~ [0-9]*ms ]]
then
duration=${BASH_REMATCH[0]}
fi
json=$(echo $json | jq \
--arg suc "$success" \
--arg fa "$failed" \
--arg rat "$rating" \
--arg dur "$duration" \
'.summary += {success:$suc|tonumber,failed:$fa|tonumber,rating:$rat|tonumber,duration:$dur}')
done
#redirect variable's output to file
echo $json | jq "." > $path"/output.json"