Awk以空格分隔的文件内容

时间:2015-03-03 03:34:41

标签: awk

我有一个文件,我想用空格或“_”分割它们的行。

其格式为

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]

我的awk脚本如下:

`#!/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  ;               
    }


}`

如上面的脚本所示,从上面的脚本我可以预期RTR是4美元。 但我发现$ 3的输出如下:

 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

我做错了什么?是awk的新手。

1 个答案:

答案 0 :(得分:2)

将您的FS值更改为[[:space:]_]+,以获得所需的标记化(拆分为字段)。

使用此语句对其进行测试,以查看识别的字段:

 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'

FS[[:space:]]|_的问题在于

  • 它一次只识别 1 字符作为分隔符
  • 它只识别 空白 _作为分隔符。

请注意,指定除FS之外的显式' '值(单个空格)会导致awk查找该分隔符的单个实例,并解释多个相邻实例分隔多个 - 因此 - 字段。

因此,在您的情况下,跨度<space>__<space>均不代表单个分隔符,而是代表字段的两个分隔符。

如果要将给定字符的 spans (运行)或某个字符集解释为单个分隔符实例,请使用复制符号+

但是,建议的FS[[:space:]_]+可能太宽容,因为它会识别任何空白混合的行和_字符。作为分隔符。

为了更具限制性,您可以使用以下FS值:

[[:space:]]+_?|_?[[:space:]]+

也就是说,如果输入函数中的_字符更像是分隔符,只包含一个字段,那么更好的解决方案可能是:

  • 使用FS的DEFAULT值,该值将运行的空格识别为分隔符
  • 从字段_中删除$3分隔符:gsub("^_|_$", "", $3)