linux文本分析利器awk命令使用详解、详细示例及linux服务器上手动释放内存和交换内存的详细介绍应用

一、linux文本分析利器awk命令使用详解及详细示例

    grep,sed,awk是linux里文本处理的三大利器,awk是行处理器(依次对每一行进行处理,然后输出),其优点是在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息 publish:August 11, 2017 -Friday。

#awk命令形式:    
awk [-F|-f|-v] 'BEGIN{} /preg/{command1; command2} END{}' file

1. awk命令选项,及命令格式详解

#选项,及命令格式详解
[-F|-f|-v]   #大参数一般不需要用,默认是为空格分界,-F指定分隔符,-f调用脚本,-v定义变量 var=value
'  '         #引用代码块
BEGIN        #初始化代码块,在对每一行进行处理之前,初始化代码
//           #内容匹配,只对匹配通过的行进行处理
{}           #命令代码块,可执行多条命令,多条命令使用分号分隔
END          #结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

命令中可用的一些变量等数据如下:
$0     #表示整个当前行,$1表示第1项,以此类推(以分隔符分开的各项,不包括分隔符)
NF     #字段数量总量,即以分隔符号分开后当前行的字段总数
NR     #每行的记录号,多文件记录递增,相当于行数
FNR    #与NR类似,不过多文件记录不递增,每个文件都从1开始
\t     #制表符
\n     #换行符
FS     #BEGIN时定义分隔符
RS     #输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~      #匹配,与==相比不是精确比较
!~     #不匹配,不精确比较
==     #等于,必须全部相等,精确比较
!=     #不等于,精确比较
&&    #逻辑与
||     #逻辑或
+      #匹配时表示1个或1个以上
*      #通配,0个或多个
FILENAME #分析的文件名
OFS    #输出字段分隔符, 默认也是空格,可以改为制表符等
ORS    #输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F'[:#/]'   #定义三个分隔符

2. AWK命令使用详细示例

以下为一个日志文件,记录了请求时间,响应状态,请求的IP,以及响应的时间。总共约50万条数据。

[root@123 ~]# wc -l s.log 
511386 s.log
[root@123 ~]# head -5 s.log 
[11/Aug/2017:00:00:02] 200 36.250.93.93" 35.25
[11/Aug/2017:00:00:02] 200 36.250.93.93" 35.25
[11/Aug/2017:00:00:02] 200 221.229.202.76" 220.229
[11/Aug/2017:00:00:02] 200 221.229.202.75" 220.229
[11/Aug/2017:00:00:02] 200 221.229.202.76" 220.229
[root@123 ~]# awk -F ':' '{print $1,$3}' s.log | head -5 #使用冒号分隔,取出第1项和第3项,
[11/Aug/2017 00
[11/Aug/2017 00
[11/Aug/2017 00
[11/Aug/2017 00
[11/Aug/2017 00
[root@123 ~]# awk -F ':' '{print $1,$3}' OFS='=' s.log | head -5  #使用冒号分隔,取出第1项和第3项,但指定了输出字段分隔符=,如下:
[11/Aug/2017=00
[11/Aug/2017=00
[11/Aug/2017=00
[11/Aug/2017=00
[11/Aug/2017=00
[root@123 ~]# head -5 s.log | awk -F ':' '{print $1,$3}' OFS='=' ORS=' -kkk- ' #指定了记录分隔符,如下就全部输出在一行上。
[11/Aug/2017=00 -kkk- [11/Aug/2017=00 -kkk- [11/Aug/2017=00 -kkk- [11/Aug/2017=00 -kkk- [11/Aug/2017=00 -kkk- [root@123 ~]# 
[root@123 ~]# awk -F '[: ]' '{print $1,$5}' s.log  | head -5    #可以指定多个分隔符,比如这里同时以冒号和空格分隔开。
[11/Aug/2017 200
[11/Aug/2017 200
[11/Aug/2017 200
[11/Aug/2017 200
[11/Aug/2017 200
[root@123 ~]# awk '{print $0}' s.log | head -2  #$0代表本行记录,如下
[11/Aug/2017:00:00:02] 200 36.250.93.93" 35.25
[11/Aug/2017:00:00:02] 200 36.250.93.93" 35.25
[root@123 ~]# awk '{print $NF}' s.log | head -2  #将每行第NF个字段的值打印出来,也就是最后一个字段。
35.25
35.25
[root@123 ~]# awk '{print NF}' s.log | head -2  #打印每行有多少个字段数
4
4
[root@123 ~]# awk '{print $1,$4}' s.log | head -2  #逗号分开打印时即以空格分开
[11/Aug/2017:00:00:02] 35.25
[11/Aug/2017:00:00:02] 35.25
[root@123 ~]# awk '{print $1$4}' s.log | head -2 #连在一起输出,和awk '{print $1 $4}' s.log | head -2 结果是一样的。
[11/Aug/2017:00:00:02]35.25
[11/Aug/2017:00:00:02]35.25
[root@123 ~]# awk '{print $1"-=-="$4}' s.log | head -2 #自定义连接字符,这个比OFS更灵活
[11/Aug/2017:00:00:02]-=-=35.25
[11/Aug/2017:00:00:02]-=-=35.25
[root@123 ~]# awk 'NF==4 {print NR,$4}' s.log | head -2 只显示只有4个字段的行。也可以使用大于小于,并且输出行号
1 35.25
2 35.25
[root@123 ~]# awk 'NR==2 || NR==3 {print NR,$4}' s.log | head -2 #只打印第2行和第3行  
2 35.25
3 220.229
[root@123 ~]# awk '/221.229/' s.log | head -2   #字符匹配,只输出包含221.229的行,和命令:awk '/221.229/{print $0}' s.log | head -2一样。
#也和这条命令:awk '/221.229/{print}' s.log | head -2 执行结果一样。
[11/Aug/2017:00:00:02] 200 221.229.202.76" 220.229
[11/Aug/2017:00:00:02] 200 221.229.202.75" 220.229
[root@123 ~]# awk '!/221.229/{print}' s.log | head -2   #取反,不匹配才输出
[11/Aug/2017:00:00:02] 200 36.250.93.93" 35.25
[11/Aug/2017:00:00:02] 200 36.250.93.93" 35.25
[root@123 ~]# awk '/:00:10:01/,/:00:10:02/{print $0}' s.log   #区间匹配,只匹配10:01秒到02秒的内容,但是注意,02秒的只匹配第一行就停止。              
[11/Aug/2017:00:10:01] 200 101.28.249.34" 100.28
[11/Aug/2017:00:10:01] 200 221.229.202.75" 220.229
[11/Aug/2017:00:10:01] 200 36.250.93.93" 35.25
[11/Aug/2017:00:10:01] 200 221.229.202.75" 220.229
[11/Aug/2017:00:10:01] 200 221.229.202.75" 220.229
[11/Aug/2017:00:10:01] 200 221.229.202.76" 220.229
[11/Aug/2017:00:10:01] 200 101.28.249.41" 100.28
[11/Aug/2017:00:10:01] 200 221.229.202.88" 220.229
[11/Aug/2017:00:10:02] 200 36.250.93.93" 35.25
[root@123 ~]# awk '/.207$/{print $0}' s.log | head -2 #指定结尾字符串必须满足的条件,也可以使用^指定开头字符串的条件。
[11/Aug/2017:00:00:11] 200 113.207.6.193" 112.207
[11/Aug/2017:00:00:14] 200 113.207.6.193" 112.207
[root@123 ~]# awk '/[3][4][5]*/{print $0}' s.log | head -2  #匹配包含3和4,5可有可无
[11/Aug/2017:00:00:03] 200 101.28.249.34" 100.28
[11/Aug/2017:00:00:07] 200 101.28.249.34" 100.28
[root@123 ~]# awk '/[3][4][5]+/{print $0}' s.log | head -2   #必须包含5,没有找到记录。
[root@123 ~]# awk '/[2][0][7]+/{print $0}' s.log | head -2   
[11/Aug/2017:00:00:11] 200 113.207.6.193" 112.207
[11/Aug/2017:00:00:14] 200 113.207.6.193" 112.207
[root@123 ~]# awk '{ if( $2 == 404 ) print $0}' s.log | head -2 #对某个字段判断是否=再输出。
[11/Aug/2017:17:58:47] 404 61.200.88.14" 60.2
[11/Aug/2017:17:58:51] 404 61.200.88.12" 60.2
[root@123 ~]# awk '{ if( $2 == 404 && $1 ~/47]/ ) print $0}' s.log | head -2   #要求404,并且是第47秒出现的行。 
[11/Aug/2017:17:58:47] 404 61.200.88.14" 60.2
[root@123 ~]# awk '{ if( $2 != 200 ) print $0}' s.log   #要求输出所有不是200的响应结果。
[11/Aug/2017:11:25:23] 304 101.28.249.32" 100.28
[11/Aug/2017:17:58:47] 404 61.200.88.14" 60.2
[11/Aug/2017:17:58:51] 404 61.200.88.12" 60.2
[root@123 ~]# awk '{if ($2 ==304 || $2 ~/404/ ) print $0}' s.log #IF语句,必须用在{}中,且比较内容用()扩起来
[11/Aug/2017:11:25:23] 304 101.28.249.32" 100.28
[11/Aug/2017:17:58:47] 404 61.200.88.14" 60.2
[11/Aug/2017:17:58:51] 404 61.200.88.12" 60.2
[root@123 ~]# awk '{if($4>0 && $4<50) print $0;else print $4}' s.log | head -5 #if else结构
[11/Aug/2017:00:00:02] 200 36.250.93.93" 35.25
[11/Aug/2017:00:00:02] 200 36.250.93.93" 35.25
220.229
220.229
220.229

3. AWK使用格式化输出

    关于awk中使用printf进行格式化输出。及BEGIN,END命令格式。

netstat -anp|awk '{printf "%-8s %-8s %-10s\n",$1,$2,$3}' 

printf表示格式输出
%格式化输出分隔符,-8长度为8个字符,s表示字符串类型

    打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8),第三个字段输出字符串类型(长度为10)

netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s \n",$1,$2,$3}'
netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s %-10s \n",NR,$1,$2,$3}'

命令使用示例:

[root@123 ~]# awk '{printf "%-16s %-7s\n",$3,$4}' s.log | head -4 #要求IP占用16位,响应时间占用6位,这样就对齐了。
36.250.93.93"    35.25  
36.250.93.93"    35.25  
221.229.202.76"  220.229
221.229.202.75"  220.229
[root@123 ~]# awk 'BEGIN{i=1};/.25$/{ if($2==200 && $4>1 && $4<40) print $0};' s.log | wc -l  #命令BEGIN
129117
[root@123 ~]# awk 'BEGIN{i=1};/.25$/{ if($2==200 && $4>1 && $4<40) {i++}};END{print i}' s.log 
129118
[root@123 ~]#

4. awk中使用数组并进行相关统计:

A,统计各种响应状态码的各数。
[root@123 ~]# awk 'BEGIN{no=1};{a[$2]++};END{for (i in a) print i,a[i]}' s.log     
200 511383
304 1
404 2
[root@123 ~]# awk '{a[$2]++};END{for (i in a) print i,a[i]}' s.log             
200 511383
304 1
404 2
[root@123 ~]# awk '{print $2}' s.log | sort | uniq -c | sort -n -k1  #也可以使用
      1 304
      2 404
 511383 200
B,计算平均响应时间

比如要求响应状态为200,且响应时间不能为-(即不要404,304等结果)

[root@123 ~]# awk 'BEGIN{t=0;n=0};{if($2==200 && $4>0) {t+=$4;n++;} } END{ print t,n,t/n}' s.log 
7.18456e+07 510623 140.702
C,统计响应时间最长的和最短的时间。
[root@123 ~]# awk 'BEGIN{min=10000000;max=0};{if($2 && $4>0 && $4<min) {min=$4}; if($2 && $4>0 && $4>max) {max=$4}; } END{ print min,max}' s.log           
13.18 222.151

二、linux服务器上手动释放内存和交换内存的详细介绍及方法

    linux中的内存占用很多时候一看都占用很大,因为linux的原则是尽可能地充分利用内存,所以大部分内存用来cache了。之前也有一篇文章:安装centos开机出现Kernel panic - not syncing: Attempted to kill init无法启动解决方法 及 linux内存一直减少-Cached占用很大的解决_attempted to kill init进不了系统-CSDN博客。Linux上清缓存是有三种选项来清除缓存(包括Buffer和Cache),清除时不用中断任何进程及服务。

仅清除页面缓存(PageCache)
# echo 1 > /proc/sys/vm/drop_caches

清除目录项和inode
# echo 2 > /proc/sys/vm/drop_caches 

清除页面缓存,目录项和inode
# echo 3 > /proc/sys/vm/drop_caches

#演示示例:执行命令前先查看下内存
[root@123 04007cn]# free -m
             total       used       free     shared    buffers     cached
Mem:           992        597        394          0        127        207
-/+ buffers/cache:        263        728
Swap:         3007          0       3007
[root@123 04007cn]# echo 1 > /proc/sys/vm/drop_caches
# 执行完后内存对比
[root@123 04007cn]# free -m
             total       used       free     shared    buffers     cached
Mem:           992        275        716          0          0         17
-/+ buffers/cache:        257        734
Swap:         3007          0       3007

上述命令说明:清除前一定要记得执行一下sync命令,sync命令是刷新文件系统缓冲区(buffer),有些执行命令比如文件修改可能还留在缓冲区未对硬盘上的物理文件进行修改,如果直接执行清除可能导致这些命令丢失,引起问题。在生产环境中建议清除1即可。

清除Linux的交换内存,可以运行下面的命令:
# swapoff -a && swapon -a

  • 28
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林戈的IT生涯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值