我正在寻求一些帮助来尝试优化兄弟网络日志解析脚本,这是背景:
我有大量的兄弟日志,但我只对查询我的范围内的IP(多个可变长度子网)感兴趣。
因此,我有一个包含正则表达式模式的文本文件来匹配我正在查找的 IP 范围:scope.txt:
/^10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5])$/
(scope.txt 在正则表达式模式中包含最多 20 行其他 IP 范围)findInScope.sh:
#!bin/sh
for file in /data/bro_logs/2016-11-26/conn.*.log.gz
do
echo "$file"
touch /tmp/$file
for nets in $(cat scope.txt)
do
echo "$nets"
zcat $file | bro-cut -d | awk '$3 ~ '$nets' || $5 ~ '$nets'' >> /tmp/$file
done
sort /tmp/$file | uniq > ~/$file
rm /tmp/$file
done
作为更多背景,原始 bro conn 日志每小时约为 100MB,因此我当前的脚本大约需要 10-20 分钟来解析一小时的日志数据。一天的日志最多可能需要 3 小时。
我考虑过使用 40 个 or 的单个 awk 语句,但决定不想这样做,因为我想要一个单独的scope.txt 文件,以便对不同的 IP 范围范围使用相同的脚本。
我还在多个 conn.log 文件(即 zcat conn.*.log.gz)上尝试了 zcat,但输出文件最终超过 1GB,我想保持每小时日志完整。
答案1
只需通过 awk 传递一次日志文件,您就会获益匪浅。这意味着将所有正则表达式合并为一个。如果您不想在scope.txt
文件中执行此操作,请在调用 awk 之前执行此操作。例如,
sed <scope.txt 's|^/\^|(|; s|\$/$|)|; $!s/$/|/' | tr -d '\n' >pattern
zcat $file | bro-cut -d |
awk '
BEGIN{ getline pat <"pattern"; pat = "^(" pat ")$" }
$3 ~ pat || $5 ~ pat
' >~/$file
sed 将每个正则表达式行周围的/^
和替换$
为一对封闭的,在该行的末尾()
添加一个,并将结果全部放在一行中放入 file 中。因此,该文件是所有模式或运算在一起的。缺失的内容被添加到 awk 脚本语句中,该语句将模式文件读取到变量 中。|
pattern
^(...)$
BEGIN
pat
上面的内容替换了您的内部for
循环,并且sort|uniq
.
答案2
最简单的答案是使用scope.txt
稍作修改的 ,作为模式文件,并使用zcat | grep
(或仅zgrep
) 来获取您需要的行。
首先,修改您的scope
文件以更改:
/^10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5])$/
进入:
(^|[^0-9.])(10\.0\.0\.([8-9]|[1-3][0-9]|4[0-5]))($|[^0-9.])
要轻松做到这一点,您可以使用:
sed -e 's:^/\^:(^|[^0-9.])(:' -e 's:\$/$:)($|[^0-9.]):' scope.txt > grepscope.txt
然后,进行搜索:
zgrep -Ehf grepscope.txt /data/bro_logs/2016-11-26/conn.*.log.gz | less
或者,因为您希望每个文件的输出单独存储:
for f in /data/bro_logs/2016-11-26/conn.*.log.gz; do
zgrep -Ehf grepscope.txt "$f" | sort -u > ~/"${f##*/}"
done
另请注意,“for”循环变量$f
将包含全部的依次到每个文件的路径;为了避免在尝试将输出定向到~/"$f"
(这将引用您的主目录中可能不存在的子目录)时出现的错误~/data/bro_logs/2016-11-26
,我们删除路径名中最后一个斜杠之前的所有内容,只使用基本名称每个日志文件的。
值得一提的标志zgrep
:
-E
指定扩展的正则表达式,以便模式中的括号不需要转义。
-h
禁止将文件名打印为每个匹配行的前缀。 (您可以在for
循环版本中省略此选项,因为默认情况下grep
仅在搜索多个文件时打印文件名,如我指定的第一个命令中所示,但将其保留在两个版本中不会造成任何损害。)
-f
让您能够指定一个模式文件。 根据您的问题,这正是您所需要的,并且 usinggrep -f
允许您使用从文件中获取的多个搜索模式,而无需构建带有大量“或”的 Awk 命令。
sort | uniq
通常可以替换为sort -u
,除非您需要使用某些uniq
选项标志。在这种情况下你不需要,所以我使用了更简单的形式sort -u
。