I have file with content:
file.txt:
Iteration 1
RAM: +456ms
Cache: +142ms (total +417ms)
Iteration 2
Spec: +152ms
Cache: +149ms (total +413ms)
Iter
One using 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
Output lines in awk default order (appears random):
Cache: 142 149
Searchms: 131 188
Spec: 152 172
RAM: 456 184 149
Simply:
#!/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
You can change the order in line 2 ( for loop )
Output:
$ cat out.txt
RAM 456 184 149
Cache 142 417 149 413
Spec 152 172
Searchms 131 385 188
$ 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
This might work for you (GNU sed):
sed -E '/:/!d;s/.([0-9]+).*/\1/;H;x;s/((\n\S+) \S+)(.*)\2(.*)/\1\4\3/;h;$!d;x;s/.//' file
Any lines other than those that contain a :
are noise, so delete them.
Remove all but the key, a space and the first set of integers from each line.
Append the result to the hold space.
Using pattern matching, gather up like keys data and retain in the hold space.
Delete all but the last line.
At the end of file, swap to the hold space, remove the introduced newline and print the result.
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
(Order of the lines will vary; pipe it to sort if that matters)
How it works:
For each line in the file, if it matches the regular expression ^(\w+):\s+\+(\d)ms
(1 or more alphanumeric characters at the start of the line, followed by a colon, whitespace, a plus sign, 1 or more digits, and then the letters m and s), it adds the number to the appropriate array in a hash using the starting word as the key. Then it prints out all those starting words and their associated arrays.
Basically the same idea as the awk answer, but that uses strings instead of arrays because awk doesn't have true arrays like perl, just associative ones (Which are called hashes in perl lingo).
Another Perl, using paragraph mode -00
perl -00 -lnE '
while(/(^\S+):.+?(\d+)/gm ) {push(@{$kv{$1}},$2)}
END { foreach(keys %kv) { print "$_ @{$kv{$_}}" } } '
with inputs
$ 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
$