Q:

Awk space-delimited file content

I have a file whose lines I want to split using either space or "_". 
Its format is 
f 5.287102213 _10_ RTR  --- 312 cbr 120 [13a a 6 800] ------- [6:0 20:0 29 20] [15] 1 0

s 5.288000000 _0_ AGT  --- 322 cbr 100 [0 0 0 0] ------- [0:0 2:0 32 0] [18]

My awk script is as follows:
`#!/usr/bin/awk -f

BEGIN {FS="[[:space:]]|_"} # use posix space or underscore for FS

{
action = $1;
time = $2;
sta = $4  ; # shifted here because underscores are delimiters
dest = $6;
app = $10;
pkt_size = $11;

#print $1
#print $2
print $5
#print $4
#print $5
#print $6
#print $7
#print $8
#print $9
#print $10

if( action == "s" && dest == "MAC" && app == "cbr"){
            startTime+=time ;
        count++;        
}

if( action == "r" && dest == "MAC" && app == "cbr"){
            endTime+=time   ;
        receivedSize+=pkt_size  ;               
    }

}`

As seen in the above script, from the above script I was expecting RTR to be in $4. 
But I find that the output of $3 is as follows:
 RTR  --- 312 cbr 120 [13a a 6 800] ------- [6:0 20:0 29 20] [15] 1 0
 AGT  --- 322 cbr 100 [0 0 0 0] ------- [0:0 2:0 32 0] [18] 0 0

 RTR  --- 322 cbr 100 [0 0 0 0] ------- [0:0 2:0 32 0] [18] 0 0

What am I doing wrong? Am new to awk. 

A:

Change your FS value to [[:space:]_]+ to get the tokenization (splitting into fields) you want.
Test it with this statement to see the fields recognized:
 awk -F'[[:space:]_]+' '{for(i=1;i<=NF;++i){print i ": " $i}}' \
   <<<'f 5.287102213 _10_ RTR  --- 312 cbr 120 [13a a 6 800] ------- [6:0 20:0 29 20] [15] 1 0'

The problem with your FS value, [[:space:]]|_, is that 

it only recognizes 1 character at a time as the separator
it only recognizes either whitespace or _ as the separator.

Note that specifying an explicit FS value other than ' ' (a single space) causes awk to look for a single instance of that separator, and interprets multiple adjacent instances as separating multiple - and thus empty - fields.
Thus, in your case, the spans <space>_ and _<space> each represent not a single separator, but two separators abutting an empty field.
If you want spans (runs) of a given character or characters from a set to be interpreted as a single separator instance, use duplication symbol +.
However, the proposed FS value, [[:space:]_]+, may be too permissive, as it would recognize a run of any mix of whitespace and _ chars. as a separator.
To be more restrictive, you could use the following FS value:
[[:space:]]+_?|_?[[:space:]]+

That said, if the _ chars in your input function more like delimiters enclosing only one field, a better solution may be:

to use the DEFAULT value of FS, which recognizes runs of whitespace as delimiters
to strip the _ delimiters from field $3: gsub("^_|_$", "", $3)

