Как конвертировать мой файл .txt в .json в bash?
У меня есть такой текстовый файл txt (где * это какой-то текст):
[ Some ping ], 1..7 pings
-----------------------------------------------------------------------------------
not ok 1 ********* ****** ******* ************ (**** ***), 6ms
not ok 2 ********* ****** ******* ************ (*** ** ** ***, *** ***), 24ms
ok 3 ********* ****** ***** (*** ** ** ***, *** ***), 21ms
ok 4 ********* ****** ******* **** (**** ***), 10ms
ok 5 ********* ****** ******* **** (*** ** ** ***, *** ***), 17ms
ok 6 ********* ****** ******* ****** (**** ***), 11ms
ok 7 ********* ****** ******* ****** (*** ** ** ***, *** ***), 28ms
-----------------------------------------------------------------------------------
5 (of 7) pings passed, 2 ping failed, percents as 61.23%, spent 127ms
Я ищу способ преобразовать это в json, как это:
{
"MainHead": Some ping",
"pings":[
{
"head": "********* ****** ******* ************ (**** ***)",
"result": false,
"time": "6ms"
},
{
"head": "********* ****** ******* ************ (*** ** ** ***, *** ***)",
"result": false,
"time": "24ms"
},
{
"head": "********* ****** ***** (*** ** ** ***, *** ***)",
"result": true,
"time": "21ms"
},
{
"head": "********* ****** ******* **** (**** ***)",
"result": true,
"time": "20ms"
},
{
"head": "********* ****** ******* **** (*** ** ** ***, *** ***)",
"result": true,
"time": "17ms"
},
{
"head": "********* ****** ******* ****** (**** ***)",
"result": true,
"time": "11ms"
},
{
"head": "********* ****** ******* ****** (*** ** ** ***, *** ***)",
"result": true,
"time": "28ms"
}
],
"total": {
"good": 5,
"bad": 2,
"percents": 61.23,
"time": "127ms"
}
}
Я пока нашел только такое решение, но оно не дает той картины которую я хочу получить.
jq -Rs '[ split("\n")[] | select(length > 0) | split(":") | {head: .[0], result: .[1], time: .[2]} ]' text.txt
Ответы (1 шт):
cat ./text.txt | egrep '^(not|ok)' | perl -pe 's/^((not\s+)?ok)\s+(\d+)\s+([^)]+\)),\s+(\d+)ms$/{"head":"$4","result":"$1","time":$5}/g; s/"ok"/true/g; s/"not ok"/false/g' | jq -s . | jq -n '.pings |= [inputs]' | jq ".MainHead=\"$(cat ./text.txt | egrep -m 1 -B 1 '^-{70,}' | head -1 | perl -pe 's/^\[([^]]*)\].*$/$1/')\"" | jq ".total={\"good\":$(cat ./text.txt | egrep '^ok' | wc -l),"bad":$(cat ./text.txt | egrep '^not ok' | wc -l),"percents":$(echo `cat ./text.txt | egrep '^ok' | wc -l`' / ('`cat ./text.txt | egrep '^not ok' | wc -l`' +'`cat ./text.txt | egrep '^ok' | wc -l`') * 100' | bc -l)}"
cat ./text.txtвыводит на экран файлegrep '^(not|ok)'фильтрует тело файла отсекая заголовок и конецperl ...преобразует строку в почти JSON- далее я заменяю
okнаtrueиnot okнаfalse(вероятно, не самый оптимальный способ, но одноразово пойдет) jq -s .делает остальную работу по формированию валидного JSON- второй
jqобрамляет массив в объект с свойствомpings - третий
jqдобавляет полеMainHead. - четвертый
jqдобавляет полеtotal.
Внутри третьего jq немного жёстковатый код. Параметры -m 1 и -B 1 означают только первое соответствие и затронуть одну строчку до соответствия, само регулярное выражение '^-{70,}' ищет строку где есть 70 и более дефисов от начала строки, head -1 отбирает первую строку из egrep, perl выбирает всё что в квадратных скобочках.
Внутри четвертого jq используется bc для подсчетов процентов.
Сумму времени добавлю позже.
Вроде норм. Правда поле MainHead добавилось в конец JSON. У меня получился вывод:
{
"pings": [
[
{
"head": "********* ****** ******* ************ (**** ***)",
"result": false,
"time": 6
},
{
"head": "********* ****** ******* ************ (*** ** ** ***, *** ***)",
"result": false,
"time": 24
},
{
"head": "********* ****** ***** (*** ** ** ***, *** ***)",
"result": true,
"time": 21
},
{
"head": "********* ****** ******* **** (**** ***)",
"result": true,
"time": 10
},
{
"head": "********* ****** ******* **** (*** ** ** ***, *** ***)",
"result": true,
"time": 17
},
{
"head": "********* ****** ******* ****** (**** ***)",
"result": true,
"time": 11
},
{
"head": "********* ****** ******* ****** (*** ** ** ***, *** ***)",
"result": true,
"time": 28
}
]
],
"MainHead": " Some ping ",
"total": {
"good": 5,
"bad": 2,
"percents": 71.42857142857143
}
}