我有大约30,000个Apache访问日志,其中一些列出了多个客户端IP地址。 这是由于Apachelogging了X-Forwarded-For头而不是客户端的IP地址。 之所以这样做,是因为我们最近在web服务器前加了haproxy。
outlook未来,我们将使用Apache的rpaf来logging只有一个IP地址,即到haproxy的连接,所以这不会是一个持续的问题。
这给我带来了实际的问题:
如何处理多个IP地址的现有日志,只提取我想要的日志。 我假设我需要sed或类似的,但我更像一个Windows的家伙,所以不是100%肯定。
规则是:
实例1,1IP
input:10.1.1.1 – – [29 / Jan / 2010:11:00:00] ….(其余的日志行)
输出:10.1.1.1 – – [29 / Jan / 2010:11:00:00] ….(其余的日志行)
示例2,2个IP
input: 10.1.1.1,10.2.2.2 – – [29 / Jan / 2010:11:00:00] ….(其余的日志行)
输出: 10.1.1.1 – – [29 / Jan / 2010:11:00:00] ….(其余的日志行)
例3,3个IP
input:10.1.1.1,10.2.2.2,10.3.3.3 – – [29 / Jan / 2010:11:00:00] ….(其余的日志行)
输出: 10.2.2.2 – – [29 / Jan / 2010:11:00:00] ….(其余的日志行)
这可以通过在日志中运行此sed命令来实现:
sed -i "s/^\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+, \)*\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\), [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+ - -/\2 - -/"
一些解释:
s/MATCH PATTERN/REPLACE PATTERN/ \2 ,其中括号中的第二部分是指匹配。 (和) ,加号: + (意思是“至less一次”)和字面字符句号: . (否则它被认为是通配符) -i选项意味着更改文件。 确保你在拷贝上工作! “这使得我的眼睛几乎和Perl一样stream血,但是它很有效。”
use strict; use warnings; use Regexp::Common qw /net/; my $ip; my $restOfLine; my @ips; while (<>) { if (/- -.*/) { $restOfLine = $&; } unless (@ips = /($RE{net}{IPv4})/g) { print; next; } if ($ips[1]) { $ip = splice(@ips,-2,1); } else { $ip = $ips[0]; } print "$ip " . $restOfLine . "\n"; }
让我的眼睛stream血less,但也许这只是我:-)