我site:
在 Google 上搜索了 Server Fault、Super User 和 Stack Overflow。我还查看了非网站特定结果,并没有看到这样的问题,所以这里...
我确实发现这个问题与 grep 和 awk 有关其中有一些很棒的知识,但我觉得没有解决文本资格挑战。这个问题还将范围扩大到任何平台和任何程序。
我有基于 NCSA 组合格式的 squid 或 apache 日志。当我说基于时,意味着文件中的前 n 个列符合 NCSA 组合标准,可能还有更多列包含自定义内容。
以下是来自 squid 组合日志的一个示例行:
1.1.1.1 - - [11/Dec/2010:03:41:46 -0500] "GET http://yourdomain.com:8080/en/some-page.html HTTP/1.1" 200 2142 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; C) AppleWebKit/532.4 (KHTML, like Gecko)" TCP_MEM_HIT:NONE
我希望能够解析
n
日志并输出特定列,以便进行排序、计数、查找唯一值等
主要的挑战和让它变得有点棘手的原因,也是为什么我觉得这个问题还没有被提出或回答,是文本资格难题。
当我发现查询语言从 grep/awk 问题开始,我非常兴奋,但后来意识到它不支持开箱即用的组合,我想我会考虑扩展它。
期待答案,并学习新知识!答案不必局限于平台或程序/语言。就这个问题而言,我最常用的平台是 Linux 或 OSX。
干杯
答案1
使用 Perl,在为 darwin-thread-multi-2level(OSX)构建的 v5.10.0 上进行测试
要打印 UserAgent 列:
perl -n -e '/^([^ ]+) ([^ ]+) ([^ ]+) (\[[^\]]+\]) "(.*) (.*) (.*)" ([0-9\-]+) ([0-9\-]+) "(.*)" "(.*)"/; print "$11\n"' -- test.log
- 选项
-n
,而每一行test.log
- 选项
-e
一行程序
我偷了并修改了我在 Google 上搜索到的 perlre来自 PHP 手册。我$
从 re 的末尾删除了 以支持基于 NCSA 组合的自定义格式。该模式可以轻松扩展以提供更多组。
正则表达式组()
最终作为局部$1
变量$n
快速而简单并且非常容易扩展和编写脚本。
管道输出的一些示例:
| sort | uniq
唯一列值| sort | uniq | wc -l
唯一列数
欢迎批评和改进
答案2
虽然它不直接解决文本限定问题,但组合格式中可以利用的一个因素是剩余的空格分隔列始终位于同一列中。因此,您可以使用带有 printf 和 NF(列数)的循环来解决这个问题
根据 awk,$0 是整个输入行,$1 是第一列,$2 是第二列,$NF 是最后一列。
因此,对于标准 NCSA 组合,用户代理是列 $13 到列 $NF
我需要删除第一列并将其与修改后的日志格式的最后一列交换(代理 IP 被添加到最后一列)。
因此应该返回的是 $NF 列,然后是第二列 ($2),然后是其余列,直到 NF - 1
我能够通过以下方式做到这一点:-
awk '{ printf "%s ", $NF; for (i=2; i<=NF-1; i++) printf "%s ", $i; printf "\n";}' < /var/log/nginx/access.log