0

我需要提取以下输出的值:

Oct  6 17:29:52 FW kernel: [ 5470.058450] ipTables: IN= OUT=eth0 SRC=192.168.1.116 DST=192.168.1.110 LEN=516 TOS=0x10 PREC=0x00 TTL=64 ID=4949 DF PROTO=TCP SPT=22 DPT=46216 WINDOW=446 RES=0x00 ACK PSH URGP=0

例如,我需要将 PROTO 的值存储在一个值中。尝试了shellscripting,我的问题是它只有在日志条目每次都处于相同顺序时才有效。

所以这不起作用:

while read line
do
        in_if=`echo $line | cut -d ' ' -f 10 | cut -d '=' -f 2`;
        out_if=`echo $line | cut -d ' ' -f 11 | cut -d '=' -f 2`;
        src_ip=`echo $line | cut -d ' ' -f 12 | cut -d '=' -f 2`;
        dst_ip=`echo $line | cut -d ' ' -f 13 | cut -d '=' -f 2`;
        pro=`echo $line | cut -d ' ' -f 20 | cut -d '=' -f 2`;
        echo "$in_if,$out_if,$src_ip,$dst_ip,$pro" >> output.csv;
done < $tmp_file
4

6 回答 6

4

Python 很方便地做到了这一点。获取所有 KEY=value 对的一般解决方案是:

import re
import fileinput

pair_re = re.compile('([^ ]+)=([^ ]+)')  # Matches KEY=value pair

for line in fileinput.input():  # The script accepts both data from stdin or a filename 

    line = line.rstrip()  # Removes final spaces and newlines
    data = dict(pair_re.findall(line))  # Fetches all the KEY=value pairs and puts them in a dictionary

    # Example of usage:
    print "PROTO =", data['PROTO'], "SRC =", data['SRC']  # Easy access to any value

这可以说比 shell 脚本更易读、更灵活、更方便。

于 2011-10-06T20:11:44.070 回答
1

你可以在不接触 Perl 的情况下做到这一点。您走在正确的轨道上,但是使用正则表达式,您可以按名称而不是位置进行搜索。

此外,您应该在 $line 周围加上引号,这样您就不会被周围的任何管道或分号灼伤。

pro=`echo "$line" | grep -o 'PROTO=\w+\+' | cut -d '=' -f 2`;

当然,如果你确实想使用 Perl,你可以做一个更巧妙的解决方案:

#!/usr/bin/perl
while(<>) {
    /IN=(\S*) .*OUT=(\S*) .*SRC=(\S*) .*DST=(\S*) .*PROTO=(\S*)/
       and print "$1,$2,$3,$4,$5\n";
}

然后调用:

./thatScript.pl logFile.txt >>output.csv
于 2011-10-06T19:45:56.490 回答
1

你甚至不需要削减:

grep -Po "(?<=PROTO=)\w+" yourFile

或者

 sed -r 's/.*PROTO=(\w+).*/\1/' yourFile

或者

awk -F'PROTO=' '{split($2,a," ");print a[1]}' yourfile

测试:

kent$  echo "Oct  6 17:29:52 FW kernel: [ 5470.058450] ipTables: IN= OUT=eth0 SRC=192.168.1.116 DST=192.168.1.110 LEN=516 TOS=0x10 PREC=0x00 TTL=64 ID=4949 DF PROTO=TCP SPT=22 DPT=46216 WINDOW=446 RES=0x00 ACK PSH URGP=0"|grep -Po "(?<=PROTO=)\w+"
TCP

kent$  echo "Oct  6 17:29:52 FW kernel: [ 5470.058450] ipTables: IN= OUT=eth0 SRC=192.168.1.116 DST=192.168.1.110 LEN=516 TOS=0x10 PREC=0x00 TTL=64 ID=4949 DF PROTO=TCP SPT=22 DPT=46216 WINDOW=446 RES=0x00 ACK PSH URGP=0"|sed -r 's/.*PROTO=(\w+).*/\1/'
TCP

kent$  echo "Oct  6 17:29:52 FW kernel: [ 5470.058450] ipTables: IN= OUT=eth0 SRC=192.168.1.116 DST=192.168.1.110 LEN=516 TOS=0x10 PREC=0x00 TTL=64 ID=4949 DF PROTO=TCP SPT=22 DPT=46216 WINDOW=446 RES=0x00 ACK PSH URGP=0"|awk -F'PROTO=' '{split($2,a," ");print a[1]}'
TCP
于 2011-10-06T19:54:00.303 回答
1

一个简单的 Perl 解决方案可能是最易读的:

#!/usr/bin/env perl

use strict; use warnings;

my $s = q{Oct  6 17:29:52 FW kernel: [ 5470.058450] ipTables: IN= OUT=eth0
SRC=192.168.1.116 DST=192.168.1.110 LEN=516 TOS=0x10 PREC=0x00 TTL=64
ID=4949 DF PROTO=TCP SPT=22 DPT=46216 WINDOW=446 RES=0x00 ACK PSH URGP=0};

while ($s =~ /(?<k> [A-Z]+) = (?<v> \S*)/xg)  {
    print "'$+{k}' = '$+{v}'\n";
}
C:\温度> z
'输入' = ''
'OUT' = 'eth0'
'SRC' = '192.168.1.116'
'夏令时' = '192.168.1.110'
'LEN' = '516'
'TOS' = '0x10'
'PREC' = '0x00'
'TTL' = '64'
'ID' = '4949'
'原型' = 'TCP'
'SPT' = '22'
'DPT' = '46216'
'窗口' = '446'
'RES' = '0x00'
'URGP' = '0'

您还可以将日志行中的信息分配给哈希:

my %entry = ($s =~ /(?<k> [A-Z]+) = (?<v> \S*)/xg);
于 2011-10-07T01:56:16.910 回答
0

在 perl 中应该这样做

#consider the $a variable has the log file my
$a = <<log file>>;
my $desired_answer;
#regex 
if ($a =~ m/PROTO=(.*?) /ig) 
{  $desired_answer=$1; }
于 2011-10-06T20:02:20.303 回答
0

感谢所有的回复!

我选择了使用 egrep 和 regex 的 shellscripting 方式...

in_if=`echo "$line" | egrep -Eo 'IN=eth[0-9]*\b' | cut -d '=' -f 2`;
out_if=`echo "$line" | egrep -Eo 'OUT=eth[0-9]*\b' | cut -d '=' -f 2`;
src_ip=`echo "$line" | egrep -Eo 'SRC=[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '=' -f 2`;
dst_ip=`echo "$line" | egrep -Eo 'DST=[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '=' -f 2`;
pro=`echo "$line" | grep -o 'PROTO=[A-Z]*\b' | cut -d '=' -f 2`;
于 2011-10-09T12:02:19.460 回答