在 Linux 服务器上使用 "find" 和正则表达式否定

Using "find" with regex-negation on Linux Server

我需要查看去年的所有 Apache 日志,看看某个 php 页面 (foobar.php) 是否曾被外部 IP 地址访问过。

所以我需要在 Apache .log 和 log.gz 文件中找到包含 foobar.php 但排除来自所有 LAN IPs (192.168.x.x).[=12 的访问的所有行=]

find 或 grep 命令可以做到吗?

这两个命令应该在所有未压缩和压缩的 Apache 访问日志中搜索 /mypage.php

grep '/mypage\.php' access.log access.log.[0-9] | grep -v '192\.168\.[0-9.]\+'     
zcat access.log*.gz | grep '/mypage\.php' | grep -v '192\.168\.[0-9.]\+' 

grep -v 否定 192\.168\.[0-9.]* 的正则表达式匹配。 zcat 类似于 gzip 压缩文件的 cat

编辑:正如@EdMorton 在评论中指出的那样,awk 可能是我们使用的更好的工具:

awk '/\/mypage\.php/ && !/192\.168\.[0-9.]+/' access.log access.log.[0-9]    
zcat access.log*.gz | awk '/\/mypage\.php/ && !/192\.168\.[0-9.]+/'

假设您的日志采用通用日志格式 (CLF),这样的事情应该可行:

zgrep -v '^192\.168\.' access.log* | grep '/foobar\.php'

像这样(未经测试)应该这样做:

find dir_where_logs_are -type f \( -name '*.log' -o -name '*.log.gz' \) -print |
while IFS= read -r file
do
    case $file in
        *.gz ) zgrep 'mypage\.php' "$file" ;;
        * ) grep 'mypage\.php' "$file" ;;
    esac
done |
grep -E -v '192\.168\.[0-9]+\.[0-9]+'

以上假定您的文件名中没有换行符。