Преобразование второго шаблона в миллисекунды в 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

Стратегия:

  1. создать для каждой строки набор пар ключ-значение 'a' => 123,'b' => 456, 'c' => 7 а также 'd' => 8
  2. умножьте каждое значение на коэффициент пересчета corect
  3. сложите числа вместе

Предположим, что мы используем awk, а пары ключ-значение хранятся в массиве a с ключом в качестве индекса.

  1. Извлечение пар ключ-значение из 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
     }
    
  2. преобразовать и суммировать: здесь мы предполагаем, что у нас есть массив f который содержит коэффициенты пересчета:

    function convert(a,f,  t,k) {
       t=0; for(k in a) t+=a[k] * f[k]
       return t
    }
    
  3. Полный код (на примере ОП)

    # 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

Другие вопросы по тегам