Распечатать файл в определенном порядке в awk - PullRequest
0 голосов
/ 15 февраля 2019

Я перехожу по этой ссылке https://stackoverflow.com/a/54599800/10220825

file.txt

Iteration 1
RAM: +2s
Cache: +142ms (total +417ms)

Iteration 2
RAM: +184ms
Cache: +172ms
Searchms: +131ms (total +385ms)

Iteration 3
RAM: +149ms
Searchms: +3.2s

Я хочу удалить ms or s из значения времени, но не из имени (например, оно не должноудалить Searchms для поиска).Также я хочу преобразовать s into ms на multiply into 1000, если значение времени содержит s и вывести результат соответственно.

Ожидаемый результат:

RAM: 2000 184 149
Cache: 142 172
Searchms: 131 3200

try.awk

/:/{vals[$1]=vals[$1] OFS $2+0}
END {
         for (key in vals)
          print key vals[key]
}

При выполнении: awk -f try.awk file.txt

Вывод кода:

Cache: 142 172
Searchms: 131 3.2
RAM: 2 184 149

В моем выводе s is not converting to ms. Пожалуйста, предложите мнекак изменить указанный выше исходный код try.awk для преобразования s в мс.


Новый тестовый пример: file.txt

Iteration 1
RAM: +2s342ms

Iteration 2
RAM: +2s

Iteration 3
RAM: +149ms

Код:

/:/ && $2 ~/ms$/{vals[$1]=vals[$1] OFS $2+0;next}
/:/ && $2 ~/[^m]s$/{vals[$1]=vals[$1] OFS ($2+0)*1000}
END {
         for (key in vals)
          print key vals[key]
}

Ожидаемый результат:

RAM: 2342 2000 149

Выход:

RAM: 2 2000 149

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Небольшая адаптация OP:

/:/{  vals[$1]=vals[$1] OFS $2*($2~/ms$/ ? 1 : 1000 ) }
END { for (key in vals) print key vals[key] }

Примечание: это не будет работать на всех версиях awk, это использует следующую изящную особенность gawk (и POSIX):

Строка преобразуется в число, интерпретируя любой числовой префикс строки как цифры: «2,5» преобразуется в 2,5, «1e3» преобразуется в 1000, , а «25fix» имеет числовое значение 25.Строки, которые нельзя интерпретировать как действительные числа, преобразуются в ноль.

источник: Руководство по Gnu Awk: преобразование строк и чисел

Это поведение действует в Posix и работает с использованием C-функции atof.POSIX, однако, предоставляет второй вариант для преобразования строк в числа, где «25fix» будет конвертировать в 0. Это, например, случай в Oracle:

Linux: GNU $ awk 'BEGIN{print "25fix"+0}'
25
SUN OS: SUNWesu $ /usr/bin/awk 'BEGIN{print "25fix"+0}'
0
SUN OS: SUNWxpg $ /usr/xpg4/bin/awk 'BEGIN{print "25fix"+0}'
25
0 голосов
/ 15 февраля 2019

Вы можете использовать следующий скрипт awk:

/:/ && $2 ~/ms$/{vals[$1]=vals[$1] OFS $2+0;next}
/:/ && $2 ~/[^m]s$/{vals[$1]=vals[$1] OFS ($2+0)*1000}
END {
         for (key in vals)
          print key vals[key]
}

. В результате вы получите:

awk -f try.awk file.txt 
Cache: 142 172
Searchms: 131 3200
RAM: 2000 184 149

Пояснения:

  • Условие $2 ~/ms$/ проверит, есть ли у нас строка с ms, в этом случае такая же логика выполняется, как и раньше, и next заставит awk перейти к следующей строке.
  • /:/ && $2 ~/[^m]s$/{vals[$1]=vals[$1] OFS ($2+0)*1000} когда мы достигаем этой области, мы знаем, что у нас есть строка с единицами в s, и мы умножаем ее на 1000, чтобы преобразовать в ms.

Чтобы ответить на ваши новые требования, я адаптировал try.awk в:

/:/ && $2 ~/[0-9]+s[0-9]+ms$/{split($2,buff,/s/);vals[$1]=vals[$1] OFS (buff[1]+0)*1000+buff[2];next}
/:/ && $2 ~/ms$/{vals[$1]=vals[$1] OFS $2+0;next}
/:/ && $2 ~/[^m]s$/{vals[$1]=vals[$1] OFS ($2+0)*1000}
END {
         for (key in vals)
          print key vals[key]
}

Ввод:

$ cat file2.txt 
Iteration 1
RAM: +2s342ms

Iteration 2
RAM: +2s

Iteration 3
RAM: +149ms

Выход:

$ awk -f try.awk file2.txt 
RAM: 2342 2000 149
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...