Преобразование второго шаблона в миллисекунды в awk
У меня есть файл с шаблоном 's', мне нужно преобразовать в 'ms', умножив на 1000. Я не могу это сделать. Пожалуйста, помогите мне.
file.txt
First launch 1
App: +1s170ms
First launch 2
App: +186ms
First launch 3
App: +1s171ms
First launch 4
App: +1s484ms
First launch 5
App: +1s227ms
First launch 6
App: +204ms
First launch 7
App: +1s180ms
First launch 8
App: +1s177ms
First launch 9
App: +1s183ms
First launch 10
App: +1s155ms
Мой код:
awk 'BEGIN { FS="[: ]+"}
/:/ && $2 ~/ms$/{vals[$1]=vals[$1] OFS $2+0;next}
END {
for (key in vals)
print key vals[key]
}' file.txt
Ожидаемый результат:
App 1170 186 1171 1484 1227 204 1180 1177 1183 1155
Выход будет:
App 1 186 1 1 1 204 1 1 1 1
Как преобразовать вышеприведенный шаблон 's' в 'ms', если появится второй шаблон.
2 ответа
Я постараюсь объяснить это немного обобщенно, а затем применить его к вашему делу.
Вопрос: у меня есть строка вида
123a456b7c8d
где числа являются числовыми целочисленными значениями любой длины, а буквы являются соответствующими единицами. У меня также есть коэффициенты пересчета из единицыa,b,c,d
объединитьf
, Как я могу преобразовать это в единое количество единицf
?Пример: из
1s183ms
в1183ms
Стратегия:
- создать для каждой строки набор пар ключ-значение
'a' => 123
,'b' => 456
,'c' => 7
а также'd' => 8
- умножьте каждое значение на коэффициент пересчета corect
- сложите числа вместе
Предположим, что мы используем awk, а пары ключ-значение хранятся в массиве a
с ключом в качестве индекса.
Извлечение пар ключ-значение из
str
:function extract(str,a, t,k,v) { delete a; t=str; while(t!="") { v=t+0; match(t,/[a-zA-Z]+/); k=substr(t,RSTART,RLENGTH); t=substr(t,RSTART+RLENGTH); a[k]=v } return }
преобразовать и суммировать: здесь мы предполагаем, что у нас есть массив
f
который содержит коэффициенты пересчета:function convert(a,f, t,k) { t=0; for(k in a) t+=a[k] * f[k] return t }
Полный код (на примере ОП)
# set conversion factors BEGIN{ f['s']=1000; f['ms'] = 1 } # print first word BEGIN{ printf "App:" } # extract string and print /^App/ { extract($2,a); printf OFS "%dms", convert(a,f) } END { printf ORS }
какие выводы:
App: 1170ms 186ms 1171ms 1484ms 1227ms 204ms 1180ms 1177ms 1183ms 1155ms
perl -n -e '$s=0; ($s)=/(\d+)s/; ($ms)=/(\d+)ms/;
s/^(\w+):/push @{$vals{$1}}, $ms+$s*1000/e;
eof && print "$_: @{$vals{$_}}\n" for keys %vals;' file`
perl -n
ничего не печатает, поскольку он проходит через вход.$s
а также$ms
установлены на эти поля.$s
гарантированно обнуляетсяs///e
набивает%vals
хеш со списком чисел в мс для каждого ключа,App
, в этом случае.eof &&
выполняет последующий код после окончания файла.print "$_: @{$vals{$_}}\n" for keys %vals
печатает%vals
хэш, как хочет ОП.
Приложение: 1170 186 1171 1484 1227 204 1180 1177 1183 1155