Awk Script to process data from a trace file

1k views Asked by At

I have a table (.tr file) with different rows (events).

**Event**     **Time**   **PacketLength**  PacketId
sent             1              100           1
dropped          2              100           1
sent             3              100           2
sent             4.5            100           3
dropped          5              100           2
sent             6              100           4
sent             7              100           5
sent             8              100           6
sent             10             100           7

And I would like to create a new table as the following and I don't know how to it in AWK.

**SentTime**       **PacketLength        Dropped**
1                         100              Yes
3                         100              Yes     
4.5                       100
6                         100
7                         100
8                         100
10                        100

I have a simple code to find dropped or sent packets, time and id but I do not know how to create a column in my table with the results for dropped packets.

BEGIN{}
{
    Event = $1;
    Time = $2;
    Packet = $6;
    Node = $10;
    id = $11;
        if (Event=="s" && Node=="1.0.1.2"){
                printf ("%f\t %d\n", $2, $6);
        }
} 
    END {}
2

There are 2 answers

3
Raul Luna On BEST ANSWER

You have to save all the information in an array to postprocess it at the end of the file. Obviously, if the file is huge, this could cause memory problems.

    BEGIN  {
            template="#sentTime\t#packetLength\t#dropped";
            }
            {
            print $0; 
            event = $1; 
            time = $2; 
            packet_length = $3;
            packet_id = $4; 
            # save all the info in an array
            packet_info[packet_id] = packet_info[packet_id] "#" packet_length "#" time "#" event;
            }
    END     {
            # traverse the information of the array 
            for( time in packet_info ) 
            {
                print "the time is: " time " = " packet_info[time];
                # for every element in the array (= packet), 
                # the data has this format "#100#1#sent#100#2#dropped"
                split( packet_info[time], info, "#" );
                # info[2] <-- 100
                # info[3] <-- 1
                # info[4] <-- sent
                # info[5] <-- 100
                # info[6] <-- 2
                # info[7] <-- dropped
                line = template; 
                line = gensub( "#sentTime", info[3], "g", line );
                line = gensub( "#packetLength", info[2], "g", line ); 
                if( info[4] == "dropped" ) 
                    line = gensub( "#dropped", "yes", "g", line );
                if( info[7] == "dropped" ) 
                    line = gensub( "#dropped", "yes", "g", line );
                line = gensub( "#dropped", "", "g", line );
                print line; 
            } # for 
            }
2
fedorqui On

I would say...

awk '/sent/{pack[$4]=$2; len[$4]=$3}
     /dropped/{drop[$4]}
     END {print "Sent time", "PacketLength", "Dropped";
         for (p in pack) 
               print pack[p], len[p], ((p in drop)?"yes":"")
     }' file

This stores the packages in pack[], the lengths in len[] and the dropped in drop[], so that they are fetched later on.

Test

$ awk '/sent/{pack[$4]=$2; len[$4]=$3} /dropped/{drop[$4]} END {print "Sent time", "PacketLength", "Dropped"; for (p in pack) print pack[p], len[p], ((p in drop)?"yes":"")}' a
Sent time PacketLength Dropped
1 100 yes
3 100 yes
4.5 100 
6 100 
7 100 
8 100 
10 100