我很擅长使用“基本?” unix命令和这个问题让我的知识更加值得考验。我想做的是从日志中grep所有IP地址(例如来自apache的access.log)并计算它们发生的频率。我可以使用一个命令执行此操作,还是需要为此编写脚本?
答案 0 :(得分:13)
至少你需要一条简短的管道。
sed -e 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*$/\1/' -e t -e d access.log | sort | uniq -c
将打印每个IP(仅适用于ipv4),前缀为计数。
我用apache2的access.log测试了它(虽然它是可配置的,所以你需要检查),它对我有用。它假设IP地址是每一行的第一件事。
sed收集IP地址(实际上它会查找4组数字,其间有句点),并用它替换整行。 -e t
如果设法进行替换,则-e d
继续到下一行,sort
删除该行(如果没有IP地址)。 uniq -c
排序.. :)并且{{1}}计算连续相同行的实例(因为我们已对它们进行排序,因此对应于总计数)。
答案 1 :(得分:2)
您可以执行以下操作(其中datafile是日志文件的名称)
egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' datafile | sort | uniq -c
编辑:错过了有关计算地址的部分,现已添加
答案 2 :(得分:2)
这里给出的答案中没有一个对我有用,所以这是一个可行的答案:
cat yourlogs.txt | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | sort | uniq -c | sort
它使用grep隔离所有ip。然后对它们进行排序,计数,然后再次对结果进行排序。
答案 3 :(得分:0)
egrep'[[:digit:]] {1,3}(。[[:digit:]] {1,3}){3}'| awk'{print $ 1}'| sort | uniq -c
答案 4 :(得分:0)
以下是我几年前写的剧本。它从apache访问日志中查找地址。我刚尝试运行Ubuntu 11.10(oneiric)3.0.0-32-generic#51-Ubuntu SMP Thu Mar 21 15:51:26 UTC 2013 i686 i686 i386 GNU / Linux 它工作正常。使用Gvim或Vim读取生成的文件,该文件将被称为unique_visits,它将列出列中的唯一ips。关键是与grep一起使用的行。这些表达式用于提取IP地址编号。仅限IPV4。您可能需要浏览并更新浏览器版本号。我为Slackware系统编写的另一个类似脚本在这里: http://www.perpetualpc.net/srtd_bkmrk.html
#!/bin/sh
#eliminate search engine referals and zombie hunters. combined_log is the original file
egrep '(google)|(yahoo)|(mamma)|(query)|(msn)|(ask.com)|(search)|(altavista)|(images.google)|(xb1)|(cmd.exe)|(trexmod)|(robots.txt)|(copernic.com)|(POST)' combined_log > search
#now sort them to eliminate duplicates and put them in order
sort -un search > search_sort
#do the same with original file
sort -un combined_log > combined_log_sort
#now get all the ip addresses. only the numbers
grep -o '[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*' search_sort > search_sort_ip
grep -o '[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*' combined_log_sort > combined_log_sort_ip
sdiff -s combined_log_sort_ip search_sort_ip > final_result_ip
#get rid of the extra column
grep -o '^\|[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*' final_result_ip > bookmarked_ip
#remove stuff like browser versions and system versions
egrep -v '(4.4.2.0)|(1.6.3.1)|(0.9.2.1)|(4.0.0.42)|(4.1.8.0)|(1.305.2.109)|(1.305.2.12)|(0.0.43.45)|(5.0.0.0)|(1.6.2.0)|(4.4.5.0)|(1.305.2.137)|(4.3.5.0)|(1.2.0.7)|(4.1.5.0)|(5.0.2.6)|(4.4.9.0)|(6.1.0.1)|(4.4.9.0)|(5.0.8.6)|(5.0.2.4)|(4.4.8.0)|(4.4.6.0)' bookmarked_ip > unique_visits
exit 0
答案 5 :(得分:0)
由于在一个 IP 地址中,3-Digits-Then-A-Dot 重复了 3 次,所以我们可以这样写:
cat filename | egrep -o "([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}"
^^^ ^ ^~~~~~~~
Up_to_3_digits. Repeat_thrice. Last_section.
使用 bash 变量甚至更短:
PAT=[[:digit:]]{1,3}
cat filename | egrep -o "($PAT\.){3}$PAT"
要仅打印文件中唯一的 IP 地址,请使用 sort --uniq
管道输出。
答案 6 :(得分:-1)
使用sed:
$ sed 's/.*\(<regex_for_ip_address>\).*/\1/' <filename> | sort | uniq -c
您可以在Inernet上搜索并查找可用于IP地址的正则表达式,并将其替换为<regex_for_ip_address>
。例如From answers to a related question on stackoverflow
答案 7 :(得分:-1)
cat access.log |egrep -o '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' |uniq -c|sort