2

我不能 100% 确定如何简单地表达我的问题,所以我很抱歉,如果这个问题已经在某个地方得到了回答,而我只是找不到它。

我所拥有的是调试日志,其中包含身份验证数据包以及一堆其他输出。我需要搜索大约 200 万行日志才能找到每个包含某个 MAC 地址的数据包。

数据包看起来像这样(略微审查):

-----------------[ header ]-----------------
Event:     Authd-Response (1900)
Sequence:  -54
Timestamp: 1969-12-31 19:30:00 (0)
---------------[ attributes ]---------------
Auth-Result = Auth-Accept
Service-Profile-SID = 53
Service-Profile-SID = 49
RADIUS-Access-Accept-Attr/WiMAX-Capability = 0x(numbers)
Session-Timeout = 3600
Service-Profile-SID = 4
Service-Profile-SID = 29
Chargeable-User-Identity = "(Numbers)"
User-Password = "(the MAC address I'm looking for)"
--------------------------------------------

然而,大约有 10 种不同的可能类型具有不同的可能长度。它们都以标题行开始,以全破折线结束。

我已经成功使用 awk 来获取代码块自己使用这个:

awk '/-----------------\[ header \]-----------------/,/--------------------------------------------/' filename.txt

但我希望能够使用它只返回包含我需要的 MAC 地址的数据包。

几天来我一直试图弄清楚这一点,但我很困惑。我可以尝试编写一个 bash 脚本,但我可以发誓我以前用 awk 做过类似的事情......

4

4 回答 4

2

这可能对您有用(GNU awk):

awk '$0~mac{printf($0.RT)}' mac="01:23:45:67:89:ab" RS="\n[-]+\n" file

mac您选择的地址在哪里。

于 2012-09-29T06:13:05.227 回答
1

单程。

假设infile具有以下内容(具有不同 MAC 的三个标头):

-----------------[ header ]-----------------
Event:     Authd-Response (1900)
Sequence:  -54
Timestamp: 1969-12-31 19:30:00 (0)
---------------[ attributes ]---------------
Auth-Result = Auth-Accept
Service-Profile-SID = 53
Service-Profile-SID = 49
RADIUS-Access-Accept-Attr/WiMAX-Capability = 0x(numbers)
Session-Timeout = 3600
Service-Profile-SID = 4
Service-Profile-SID = 29
Chargeable-User-Identity = "(Numbers)"
User-Password = "ab:89:67:45:23:01"
--------------------------------------------
-----------------[ header ]-----------------
Event:     Authd-Response (1900)
Sequence:  -54
Timestamp: 1969-12-31 19:30:00 (0)
---------------[ attributes ]---------------
Auth-Result = Auth-Accept
Service-Profile-SID = 53
Service-Profile-SID = 49
RADIUS-Access-Accept-Attr/WiMAX-Capability = 0x(numbers)
Session-Timeout = 3600
Service-Profile-SID = 4
Service-Profile-SID = 29
Chargeable-User-Identity = "(Numbers)"
User-Password = "01:23:45:67:89:ab"
--------------------------------------------
-----------------[ header ]-----------------
Event:     Authd-Response (1900)
Sequence:  -54
Timestamp: 1969-12-31 19:30:00 (0)
---------------[ attributes ]---------------
Auth-Result = Auth-Accept
Service-Profile-SID = 53
Service-Profile-SID = 49
RADIUS-Access-Accept-Attr/WiMAX-Capability = 0x(numbers)
Session-Timeout = 3600
Service-Profile-SID = 4
Service-Profile-SID = 29
Chargeable-User-Identity = "(Numbers)"
User-Password = "00:00:45:67:89:ab"
--------------------------------------------

运行以下awk脚本:

awk -v mac="01:23:45:67:89:ab" '
    BEGIN { 
        RS = "-+\\[ header \\]-+"; 
        FS = "\n"; 
    } 
    ## Save record separator. I must do at the beginning because later the
    ## variable is reset. ¿Bug?
    FNR == 1 {
        record_sep = RT;
    }
    { 
        ## Go throught each line searching for the MAC. If found print
        ## the whole block.
        for (i = 1; i <= NF; i++ ) { 
            if ( match( $i, mac ) > 0 ) {
                print record_sep, $0;
                break;
            }
        } 
    }
' infile

这会产生:

-----------------[ header ]----------------- 
Event:     Authd-Response (1900)
Sequence:  -54
Timestamp: 1969-12-31 19:30:00 (0)
---------------[ attributes ]---------------
Auth-Result = Auth-Accept
Service-Profile-SID = 53
Service-Profile-SID = 49
RADIUS-Access-Accept-Attr/WiMAX-Capability = 0x(numbers)
Session-Timeout = 3600
Service-Profile-SID = 4
Service-Profile-SID = 29
Chargeable-User-Identity = "(Numbers)"
User-Password = "01:23:45:67:89:ab"
--------------------------------------------
于 2012-09-28T21:43:45.323 回答
0

一些 awks 支持多字符记录分隔符。如果 '--------' 行总是相同的长度,那么

 awk 'BEGIN{ORS=RS="^---------------------$";}/macAddress/{print}' logfile 

应该管用。

(当然,扩展 '----' 以匹配您真正的记录分隔符的长度。

IHTH

于 2012-09-28T21:30:17.150 回答
0
awk -v mac=MACADDR '
     /^-----------------\[ header \]-----------------$/ { inpacket=1; found=0 }
     inpacket { packet = packet "\n" $0; if (/User-Password = / && $3 == mac) { found=1 } }
     /^--------------------------------------------$/ && found { print packet; inpacket=0 }'

我假设上面示例中的引号和括号实际上不是文件格式的一部分。如果是,请将第一行更改为:

awk -v mac='"('MACADDR')"' '
于 2012-09-28T21:36:30.207 回答