0

我正在使用如下语句查看我的 access_logs:

cat access_log | grep 16/Sep/2012:17 | awk '{print $12 $13 $14 $15 $16}' | sort | uniq -c | sort -n | tail -40

目的是查看过去一小时内访问我的服务器的任何人的用户代理,按点击次数排序。我的服务器有异常活动,我想阻止任何不需要的蜘蛛/等。

但是 part:awk '{print $12 $13 $14 $15 $16}'会更喜欢这样的东西:awk '{print $12-through-end-of-line}'这样我就可以看到整个用户代理,每个用户代理的长度都不同。

有没有办法用 awk 做到这一点?

4

5 回答 5

2

不是非常优雅,但这有效:

grep 16/Sep/2012:17 access_log | awk '{for (i=12;i<=NF;++i) printf "%s ",$i;print ""}'

它的副作用是将字段之间的多个空格压缩为一个,并在行尾放置一个额外的空格,但这可能并不重要。

于 2012-09-21T18:33:47.933 回答
2

我从来没有找到过;在这种情况下,我使用cut(假设我不需要awk灵活处理字段分离):

# Assuming tab-separated fields, cut's default
grep 16/Sep/2012:17 access_log | cut -f12- | sort | uniq -c | sort -n | tail -40

# For space-separated fields (single spaces, not arbitrary amounts of whitespace)
grep 16/Sep/2012:17 access_log | cut -d' ' -f12- | sort | uniq -c | sort -n | tail -40

(澄清:我从来没有找到一个方法。我在必要时使用了@twalberg 的 for 循环,但cut如果可能的话更喜欢使用。)

于 2012-09-21T18:34:12.857 回答
1
$ echo somefields:; cat somefields ; echo from-to.awk: ; \
  cat from-to.awk ; echo ;awk -f from-to.awk  somefields 
somefields:
a b c d e f g h i j k l m n o p q r s t u v w x y z
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
from-to.awk:
{ for (i=12; i<=NF; i++) { printf "%s ", $i }; print "" }

l m n o p q r s t u v w x y z 
12 13 14 15 16 17 18 19 20 21 

来自男人 awk:

NF 当前输入记录中的字段数。


所以你基本上循环遍历从 12 到最后一个的字段(用空格分隔)。

于 2012-09-21T18:50:24.547 回答
0

为什么不

  #!/bin/bash
  awk "/$1/"'{for (i=12;i<=NF;i++) printf("%s ", $i) ;printf "\n"}' log | sort | uniq -c | sort -n | tail -40 

在脚本文件中。

然后你可以这样称呼它

 myMonitor.sh 16/Sep/2012:17

没有办法测试这个权利。对任何格式/语法错误的道歉。希望你明白这一点。

IHTH

于 2012-09-21T18:35:50.313 回答
0
awk '/16/Sep/2012:17/{for(i=1;i<12;i++){$i="";}print}' access_log| sort | uniq -c | sort -n | tail -40
于 2012-09-24T10:30:47.673 回答