持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
买了一台个人服务器,跑了一个应用:
- 应用起不来了,是什么问题? 看日志?看配置有没有问题?
- 想统计下现在应用的访问ip有多少,有没有异常ip?
怎么检索这些日志,或者统计日志?
-
如果是在公司,阿里云提供了SLS日志服务,可以帮助我们很好的做这件事,好用确实真的好用,各种检索语法,各种统计函数,还可以使用SQL进行统计,只是价格有点贵...
-
成本再低一点的方式,自己搭建ELK服务,也可以方便的检索日志,不过ELK比较吃内存,一般要单独准备机器,也需要一点预算... 比SLS会便宜点
个人开发者,只有一台小型的服务器,跑个应用程序机器就快跑不动了,也不想增加额外开支,遇到了问题,那就使用Linux自带的文本检索统计工具吧。
Linux自带的工具非常多,但是功能强大的文本处理有grep、sed、awk,也被称为文本三剑客;对于日志排查,或者处理配置文件都很有帮助。
其余的文本处理命令相对比较简单:
- cat 直接输出文件的全部内容
- less 查看文件的全部内容,同时可以搜索
- tail 从尾部查看文件的内容
- tail -f 查看文件内容,并且持续监控日志输出
- head 查看文件头部内容
- ...
接下来详细介绍这三个功能强大的文本工具:
Grep - 搜索目标内容
Grep说起来其实就专注做一件事情,匹配目标文本;使用正则表达式搜索目标内容。 可以对单个文件进行搜索,可以对目录进行搜索,可以对命令行中的管道输出进行搜索... 各种文本搜索。
语法
grep [OPTIONS] PATTERN [FILE...]
# grep -e等于egrep,支持正则搜索
grep [OPTIONS] -e PATTERN ... [FILE...]
PATTERN即要搜索的正则规则,OPTIOSN可以控制如何输出匹配到的内容。
常用选项介绍:
-A<显示行数>:除了显示符合范本样式的那一列之外,并显示该行之后的内容。 After
-B<显示行数>:除了显示符合样式的那一行之外,并显示该行之前的内容。 Before
-C<显示行数>:除了显示符合样式的那一行之外,并显示该行之前后的内容。 Context
-i 忽略字符大小写的差别。
-c: 统计匹配的行数
-n: 显示匹配的行号
-o: 仅显示匹配到的字符串
-q: 静默模式,不输出任何信息
-s: 不显示错误信息。
-v: 显示不被pattern 匹配到的行,相当于[^] 反向匹配
-w :匹配 整个单词
案例
测试文件:
# lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch
Distributor ID: AlibabaCloud
Description: Alibaba Cloud Linux release 3 (Soaring Falcon)
Release: 3
Codename: SoaringFalcon
1、忽略大小写匹配;
忽略大小写匹配cloud
lsb_release -a | grep -i cloud
2.查看匹配内容的行数
查看匹配内容在哪一行;
lsb_release -a | grep -i -n cloud
3. 打印匹配内容上下文内容
打印文件的前一行,后一行,上下行
lsb_release -a | grep -A 1 Release
lsb_release -a | grep -B 1 Release
lsb_release -a | grep -C 1 Release
4. 精确匹配单词
精确匹配某个单词:
lsb_release -a | grep -w Cloud
5. 正则表达式匹配内容
正则表达式匹配文件内容,并且只展示检索到的内容;
egrep -o 'client(.*)? server' /var/log/nginx/error.log
其他常用的正则规则:
?前面的字符是可选的和只匹配一次*前面的字符可以匹配0此或者更多次+前面的字符至少匹配一次,可以匹配更多次 {n} 前面的字符精确匹配 n 此 {n,}前面的字符匹配n此以上 {,m}前面的字符至多匹配m次 ():向后引用,引用:\1, \2, \3 ^ 行首锚定,用于模式的最左侧 行尾锚定,用于模式的最右侧 `^` 空行,去除空行一般是egrep -v '^$' file
Sed - 修改目标内容
Sed(stream editor)流失编辑器,grep命令是用来做文本搜索的,那么sed命令除了搜索之外还包含:文本新增,替换,文本删除
Sed一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(patternspace ),接着用sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’ 的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出或-i。
语法
sed script [-Ealn] [-i extension] [file ...]
sed [-Ealn] [-i extension] [-e script] ... [-f script_file] ... [file ...]
-e 指定脚本,可以指定多个脚本
-f 指定读取脚本的文件
-n 静默模式,取消控制台输出,如果与-p结合使用的话,打印指定内容
-i 输出到原文件,就是修改原文件内容
script:
a 新增
d 删除
i 插入
p 打印
s 替换
案例
还是通过实际案例,学习下如何使用Sed吧;
1. 打印目标内容,行范围、匹配
查看文本中的某些行的内容,和Grep功能比较类似
#多打印第二行
lsb_release -a | sed '2 p'
# 只打印第二行
lsb_release -a | sed -n '2 p'
# 只打印2,4行
lsb_release -a | sed -n '2,4 p'
# 只打印匹配到的行
lsb_release -a | sed -n '/Cloud/ p'
# 忽略大小写打印匹配到的行
lsb_release -a | sed -n '/Cloud/I p'
2. 在输出中新增内容
在文件中新增某些内容:i,a
# 第一行下面新增aihe
lsb_release -a | sed '1a aihe'
# 第一行上面新增aihe
lsb_release -a | sed '1i aihe'
# 匹配到clound之后新增aihe
lsb_release -a | sed '/cloud/Ia aihe'
3. 删除输出中的匹配内容
删除某些不需要的行,和打印命令是一对相反操作,了解了打印,删除页也没问题。
# 删除文件的1~3行
lsb_release -a | sed '1,3d'
# 删除文件的第一行
lsb_release -a | sed '1d'
# 删除文件中匹配到的某些内容
lsb_release -a | sed '/Cloud/d'
4. 替换输出中的匹配内容
直接替换掉文件中的某些内容,这个比较常用,直接使用命令替换文件内容。
# 替换掉文件行中第一次出现的cloud为aihe
lsb_release -a | sed 's/Cloud/aihe/'
# 只替换文件中第二行出现的Cloud
lsb_release -a | sed '2s/Cloud/aihe/'
# 文件中所有出现过的Cloud都替换为aihe
lsb_release -a | sed '2s/Cloud/aihe/g'
# 替换一行中第二次出现的字符
lsb_release -a | sed 's/Cloud/aihe/2'
AWK - 文件内容统计
Awk是一种脚本语言,主要用于操作数据和生成报告(数据统计)。 Awk有很多内建的功能,比如数组、函数等,不过一般简单的使用方式就足以满足绝大部分诉求了。
语法
awk -f programfile file
awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ...
# 常用的命令选项
-f progfile awk程序文件,awk从-f指定的文件中读取要执行的awk程序。
-F fs 指定awk以什么作为分隔符
-v var=val 分配变量
AWK内置了一些变量,可以在命令行中直接使用:
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 记录中总的列数;
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。
$NF是number finally,表示最后一列的信息,跟变量NF是有区别的,变量NF统计的是每行列的总数
如果有不确定的内置变量信息, 可以直接man awk,内部会对这些变量有些解释。自定义变量同上面的命令行选项: -v var1=v1
案例
1. 按分隔符分隔内容查看
读取所有java进程的pid,以及当前进程的用户,awk默认使用 空格或者\t作为分隔符。
ps -ef | grep java | grep -v grep | awk '{print $1,$2}'
从/etc/passwd中查看系统中所有的用户
-F 制定分隔符为: 然后直接执行打印动作即可。
awk -F: '{ print $1 }' /etc/passwd
2. 使用内置变量统计内容
打印监听的端口与当前端口对应的行数
- NR,上面说到NR是AWK的内置变量;
ss -tnl | awk '{print NR,$4}'
统计当前系统的网络状态
- $NF 使用最后一列的字段值
netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
3. 对某列统计计数与排序
统计Nginx中访问次数前10的IP地址以及个数:
cat access.log | awk '{++state[$1]} END {for(key in state) print state[key],"\t",key}' | sort -n -r | head -n 10
Nginx中有错误日志的IP地址以及错误访问次数:
awk -F'client' '{print $2}' error.log | awk '{print $2,$7}' | awk -F',' '{++state[$1]} END {for(key in state) print state[key],"\t",key}' | sort -n -r
总结
- 个人服务器有时候需要到服务器上捞一些日志,统计一些日志,Linux自带的命令可以帮助我们很好的做这件事,便宜并且功能强大.
- Grep主要用于文件搜索,Sed用于文件的修改,Awk用于文件内容的统计;
- 然后分享了下一些常用的grep、sed、awk命令案例;
最后还要提下Linux的命令在单机模式下确实非常的强大,但是在生产环境的时候,一般是集群部署,还需要辅助一些运维工具,批量执行命令。 但是如果是单机模式,掌握了这几个命令,应对绝大多数场景都没问题。
希望能对大家有所帮助。