Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print file in particular order in bash

Tags:

bash

shell

sed

awk

I have file with content:

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

In this file between every First launch, content can be different, it is not fixed ( for example: First launch 3 contain three elements while First launch 2 contents only 2 elements), so any number of content can be between the First launch pattern which is not known at the beginning.

Expected Output:

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

Due to not knowing exact approach,I have tried this code.

My code:

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

My output has two issues: I am generating the file for each pattern which is wrong. Also I wanted to remove ms after the time but it also removes the ms from the pattern name (ex: Searchms to Search)

Output:

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

Please suggest me an approach to get the expected output without generating any extra file with the constraint of removing ms after the time.

like image 240
Ratnesh Avatar asked Dec 08 '22 12:12

Ratnesh


2 Answers

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
like image 145
James Brown Avatar answered Dec 11 '22 12:12

James Brown


$ 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
like image 32
Ed Morton Avatar answered Dec 11 '22 12:12

Ed Morton