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

У меня есть файл с содержимым:

file.txt:

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

Iteration 2
Spec: +152ms
Cache: +149ms (total +413ms)

Iteration 3
RAM: +184ms
Spec: +172ms
Searchms: +131ms (total +385ms)

First launch 4
RAM: +149ms
Searchms: +188ms

В этом файле между каждыми First launch содержимое может быть разным, оно не исправлено (например:Первый запуск 3 содержит три элемента, а первый запуск 2 содержит только 2 элемента), поэтому любое число содержимого может находиться между шаблоном First launch, который неизвестен в начале.

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

RAM  456 184 149
Cache 142 149  
Spec 152 172
Searchms 131 188

Из-за незнания точного подхода я попробовал этот код.

Мой код:

for i in {1..4}
do
awk "/First launch $i/{flag=1;next} /First launch $((i+1))/{flag=0} flag" file.txt> fl$i.txt
sed -i 's/\+//g' fl$i.txt
sed -i 's/://g' fl$i.txt
sed -i 's/(.*//g' fl$i.txt
sed -i 's/ms//g' fl$i.txt
awk '{print $1 "\t" $2}' fl$i.txt
done

У меня есть две проблемы: я генерирую файл для каждого шаблоначто неправильно.Также я хотел удалить ms через некоторое время, но он также удаляет ms из имени шаблона (например: Searchms to Search)

Вывод:

fl1.txt: 
    RAM     456
    Cache   142
fl2.txt : 
    Spec    152
    Cache   149
fl3.txt  :
    RAM     184
    Spec    152
    Search  131
fl4.txt : 
    RAM     149
    Search  188

Пожалуйста, предложите мнеподход для получения ожидаемого результата без генерации какого-либо дополнительного файла с ограничением удаления ms по истечении времени.

Ответы [ 6 ]

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

Другой Perl, использующий режим абзаца -00

perl -00 -lnE ' 
               while(/(^\S+):.+?(\d+)/gm ) {push(@{$kv{$1}},$2)} 
            END { foreach(keys %kv) { print "$_ @{$kv{$_}}" } }    '

со входами

$ cat arya.txt
First launch 1
RAM: +456ms
Cache: +142ms (total +417ms)

First launch 2
Spec: +152ms
Cache: +149ms (total +413ms)

First launch 3
RAM: +184ms
Spec: +172ms
Searchms: +131ms (total +385ms)

First launch 4
RAM: +149ms
Searchms: +188ms

$ perl -00 -lnE ' while(/(^\S+):.+?(\d+)/gm ) {push(@{$kv{$1}},$2)} END { foreach(keys %kv) { print "$_ @{$kv{$_}}" } } ' arya.txt
RAM 456 184 149

Cache 142 149

Searchms 131 188

Spec 152 172


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

Просто:

#!/bin/bash
for i in RAM Cache Spec Searchms; do
    echo "$i `cat file.txt  | grep $i | grep -Eo '[0-9]{1,9}' | tr '\n' ' '`" >> out.txt
done

Вы можете изменить порядок в строке 2 (для цикла)

Вывод:

$ cat out.txt 
RAM 456 184 149 
Cache 142 417 149 413 
Spec 152 172 
Searchms 131 385 188 
0 голосов
/ 08 февраля 2019
$ cat tst.awk
BEGIN { FS="[: ]+" }
/:/ { vals[$1] = vals[$1] OFS $2+0 }
END { for (key in vals) print key vals[key] }

$ awk -f tst.awk file
Cache 142 149
RAM 456 184 149
Searchms 131 188
Spec 152 172
0 голосов
/ 08 февраля 2019

Это может работать для вас (GNU sed):

sed -E '/:/!d;s/.([0-9]+).*/\1/;H;x;s/((\n\S+) \S+)(.*)\2(.*)/\1\4\3/;h;$!d;x;s/.//' file

Любые строки, кроме тех, которые содержат :, являются шумом, поэтому удалите их.

Удалите все, кромеkey, пробел и первый набор целых чисел из каждой строки.

Добавьте результат к пробелу удержания.

Используя сопоставление с образцом, соберите как данные ключа и сохраните в пробел удержания.

Удалите все, кроме последней строки.

В конце файла перейдите в область удержания, удалите введенную новую строку и напечатайте результат.

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

Perl one-liner:

$ perl -nE 'if (/^(\w+):\s+\+(\d+)ms/) { push @{$keys{$1}}, $2 } END { while (($k, $vs) = each %keys) { say join(" ", $k, @$vs) }}' file.txt
Spec 152 172
Searchms 131 188
Cache 142 149
RAM 456 184 149

(порядок строк будет разным; передайте его для сортировки, если это важно)


Как это работает:

Для каждой строки в файле, если она соответствует регулярному выражению ^(\w+):\s+\+(\d)ms (1 или более буквенно-цифровых символов в начале строки, за которыми следуют двоеточие, пробел, знак плюс, 1 или более цифр, а затембуквы m и s), он добавляет число к соответствующему массиву в хэше, используя начальное слово в качестве ключа.Затем он выводит все эти начальные слова и связанные с ними массивы.

По сути, та же идея, что и в ответе на awk, но в нем используются строки вместо массивов, поскольку в awk нет истинных массивов, таких как perl, только ассоциативные (Которые в perl lingo называются хешами).

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

Один, использующий awk:

$ awk '
$1 !~ /^(|First)$/ {            # avoid forbidden keywords and empty lines
    gsub(/[^0-9]/,"",$2)        # remove non-numerals
    a[$1]=a[$1] OFS $2          # append to associative array 
}
END {                           # in the end
    for(i in a)                 # loop all keywords
        print i a[i]            # output
}' file

Выходные строки в порядке по умолчанию (отображается случайным образом):

Cache: 142 149
Searchms: 131 188
Spec: 152 172
RAM: 456 184 149
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...