awk space-定界文件内容
Awk space-delimited file content
我有一个文件,我想使用 space 或“_”拆分其行。
它的格式是
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 = ;
time = ;
sta = ; # shifted here because underscores are delimiters
dest = ;
app = ;
pkt_size = ;
#print
#print
print
#print
#print
#print
#print
#print
#print
#print
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 的新手。
将您的 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 个字符作为分隔符
- 它只识别或者白色space或者
_
作为分隔符。
请注意,指定 FS
值而非 ' '
(单个 space)会导致 awk 查找 单个 实例该分隔符,并将多个相邻实例解释为分隔多个 - 因此 empty - 字段。
因此,在您的情况下,跨度 <space>_
和 _<space>
各自代表的不是一个单独的分隔符,而是两个分隔符邻接一个 空 字段。
如果您希望将给定字符的 spans (运行s) 解释为 single 分隔符实例,使用重复符号 +
.
但是,提议的 FS
值 [[:space:]_]+
可能 过于宽松 ,因为它会识别 运行 白色 space 和 _
字符的任意组合。作为分隔符。
为了更具限制性,您可以使用以下 FS
值:
[[:space:]]+_?|_?[[:space:]]+
就是说,如果您的输入函数中的 _
字符更像 delimiters 仅包含 一个字段 ,则更好解决方案可能是:
- 使用
FS
的默认值,它将白色space的运行s识别为分隔符
- 从字段
</code> 中删除 <code>_
分隔符:gsub("^_|_$", "", )
我有一个文件,我想使用 space 或“_”拆分其行。
它的格式是
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 = ;
time = ;
sta = ; # shifted here because underscores are delimiters
dest = ;
app = ;
pkt_size = ;
#print
#print
print
#print
#print
#print
#print
#print
#print
#print
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 的新手。
将您的 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 个字符作为分隔符
- 它只识别或者白色space或者
_
作为分隔符。
请注意,指定 FS
值而非 ' '
(单个 space)会导致 awk 查找 单个 实例该分隔符,并将多个相邻实例解释为分隔多个 - 因此 empty - 字段。
因此,在您的情况下,跨度 <space>_
和 _<space>
各自代表的不是一个单独的分隔符,而是两个分隔符邻接一个 空 字段。
如果您希望将给定字符的 spans (运行s) 解释为 single 分隔符实例,使用重复符号 +
.
但是,提议的 FS
值 [[:space:]_]+
可能 过于宽松 ,因为它会识别 运行 白色 space 和 _
字符的任意组合。作为分隔符。
为了更具限制性,您可以使用以下 FS
值:
[[:space:]]+_?|_?[[:space:]]+
就是说,如果您的输入函数中的 _
字符更像 delimiters 仅包含 一个字段 ,则更好解决方案可能是:
- 使用
FS
的默认值,它将白色space的运行s识别为分隔符 - 从字段
</code> 中删除 <code>_
分隔符:gsub("^_|_$", "", )