grep & awk 常见的命令
grep
通常grep解决行内匹配问题,跨行建议awk
-
从一个文件中查找指定字符
grep "something" test_file
-
从多个文件中查找指定字符
grep "something" demo_*
-
查询时忽略大小写
grep -i 运行 ipconfig | grep -i ipv4 结果如下 IPv4 Address. . . . . . . . . . . : 192.168.88.1 IPv4 Address. . . . . . . . . . . : 192.168.26.1 IPv4 Address. . . . . . . . . . . : 10.200.9.234 IPv4 Address. . . . . . . . . . . : 172.27.192.1
-
使用正则表达式
grep过滤文本很强大的地方就在于和正则结合
-
全匹配,不能是子字符串
grep -w 运行 ipconfig | grep -w IPv4 结果如下 IPv4 Address. . . . . . . . . . . : 192.168.88.1 IPv4 Address. . . . . . . . . . . : 192.168.26.1 IPv4 Address. . . . . . . . . . . : 10.200.9.234 IPv4 Address. . . . . . . . . . . : 172.27.192.1
-
在地址中递归查询
grep -r 查询当前目录及其子目录
-
过滤掉指定的匹配
grep -v 运行 ipconfig | grep -w -v IPv4 结果如下,可见剔除掉了IPv4的条目 Wireless LAN adapter WLAN: Connection-specific DNS Suffix . : IPv6 Address. . . . . . . . . . . : 2001:da8:801e:1894:2c3a:4af7:c37e:e76c Temporary IPv6 Address. . . . . . : 2001:da8:801e:1894:5ca3:ccaa:cffd:484 Link-local IPv6 Address . . . . . : fe80::ee5:c3c0:44e9:9aa%20 Subnet Mask . . . . . . . . . . . : 255.255.248.0 Default Gateway . . . . . . . . . : fe80::1630:4ff:fe7d:bb05%20 10.200.15.254
-
计算匹配的数量
grep -c 运行 ipconfig | grep -w -c IPv4 结果如下 4
-
显示匹配的文件名
grep -l
-
显示行数
grep -n 运行 ipconfig | grep -w -n IPv4 结果如下 24: IPv4 Address. . . . . . . . . . . : 192.168.88.1 32: IPv4 Address. . . . . . . . . . . : 192.168.26.1 42: IPv4 Address. . . . . . . . . . . : 10.200.9.234 61: IPv4 Address. . . . . . . . . . . : 172.27.192.1
-
与管道结合查询指定进程信息
ps -ef | grep...
awk
适合场景:对文本(日志场景)或字符串进行切割处理,适合有规范格式的文件,对不规范的文件,则适合用sed处理
awk内建变量: NR当前行数(Number of Row) NF 每行字段总数(Number of Font)
BEGIN和END: BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。
任何在BEGIN之后列出的操作(在{}内)将在Unix awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。
换句话说:BEGIN后面{}的先执行,执行结果由END后{}输出。
打印文件的第一列(域) awk '{print $1}' filename
打印文件的前两列(域) awk '{print $1,$2}' filename
打印完第一列,然后打印第二列 awk '{print $1 $2}' filename
打印文本文件的总行数 awk 'END{print NR}' filename
打印文本第一行 awk 'NR==1{print}' filename
-
指定行序号输出
head -5 users | awk '{print NR,$1}' 输出结果 1 112.15.3.63 2 112.15.3.63 3 112.34.110.149 4 114.80.30.78 5 114.80.30.78
-
输出文件行数
cat users | awk 'END{print(NR)}' 输出结果:25592
-
条件控制语句
head users | awk '{if($11>300) print($1,$11)}' 注$1为ip,$11为记录的状态码 输出结果: 106.12.144.142 200 106.12.144.116 200
-
循环语句
head users | awk '{for(c=2;c<NF;c++) print $c}' 从第二列开始,依次输出到结尾
-
计算状态码分布,sort正序排列
cat users | awk '{print $11}' | sort -n | uniq -c 注:-C表示在每列旁边显示该行重复出现的次数。 117 200 592 206 注:206状态码表示请求已成功处理,但仅返回部分内容 148 302 注:302状态码表示资源被重定向 3 304 注:304状态码代表的意思是 请求资源与本地缓存相同,未修改表示经过本地缓存的内容和服务器端对比,资源未变化,不需要重新拉取资源,可以使用本地缓存数据,从而节省网络流量
-
取出第一列,覆盖输入(追加输入用»)到demo.txt中
cat test.txt | awk '{print $1}' > demo.txt
-
一些数学运算,例如求平均
cat data.txt | awk '{sum+=$1} END {print "Average = ", sum/(NR)}'