下面所说的是Linux中最重要的三个命令在业界被称为“三剑客”,它们是awk,sed,grep。
我们现在知道Linux下一切皆文件,对Linux的操作就是对文件的处理,那么怎么能更好的处理文件呢?这就要用到我们上面的三剑客命令。
在说这三个命令前我们要插入一个小插曲就是“正则表达式”。
所谓的正则表达式我个人理解就是正规的表示方法。他是用简单的方法来实现强大的功能,所以深受计算机爱好者的使用。
三剑客与正则表达式是什么关系呢?
我们可以这样理解,三剑客就是普通的命令,有的把他们叫做工具,在我看来都一样。而正则表达式就好比一个模版。三剑客能读懂这个模版。就这么简单。注意只有三剑客才能读懂这个模版哦!
现在他们的关系和功能都搞懂了,接下来我们就来认识下他们怎么结合的。正则表达式是一个模版,这个模版是由一些普通字符和一些元字符组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义。具体如下
|
元字符 |
功能 |
意思 |
|
^ |
匹配行首 |
表示以某个字符开头 |
|
$ |
匹配行尾 |
表示以某个字符结尾 |
|
^$ |
空行的意思 |
表示空行的意思 |
|
. |
匹配任意单个字符 |
表示任意一个字符 |
|
* |
字符* 匹配0或多个此字符 |
表示重复的任意多个字符 |
|
\ |
屏蔽一个元字符的特殊含义 |
表示去掉有意义的元字符的含义 |
|
[] |
匹配中括号内的字符 |
表示过滤括号内的字符 |
|
.* |
代表任意多个字符 |
就是代表任意多个字符 |
|
lele\{n\} |
用来匹配前面lele出现次数。n为次数 |
就是统计前面lele出现的次数 |
|
lele\{n,\} |
含义同上,但次数最少为n |
从功能就可以看出 |
|
lele\{n,m\} |
含义同上,但lele出现次数在n与m之间 |
从功能也可以看出 |
三剑客的功能非常强大,但我们只需要掌握他们分别擅长的领域即可:grep擅长查找功能,sed擅长取行和替换。awk擅长取列。
文本过滤(模式:pattern)工具,grep, egrep
grep [options] pattern [file...]
--color=auto 对匹配到的文本着色显示-v 显示不被pattern匹配到的行-i 忽略字符大小写-n 显示匹配的行号-c 统计匹配的行数-o 仅显示匹配到的字符串-q 静默模式,不输出任何信息-A # after, 后#行-B # before, 前#行-C # context, 前后各#行-e 实现多个选项间的逻辑or关系grep –e ‘cat ’ -e ‘dog’ file-w 匹配整个单词-E 使用ERE,相当于egrep-F 相当于fgrep,不支持正则表达式举例子:
grep -n root passwd #查找文件内容包含root的行数
grep -nv root passwd #查找文件内容不包含root的行
grep ^s passwd #查找以s开头的行
grep -n n$ passwd #查找以n结尾的行
sed是一种流编辑器,作用是实现对文件的增删改查,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’ 的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
sed [option]... ‘script‘ inputfile
sed 流编辑器,实现对文件的增删改查
选项:
-n 屏蔽默认输出
-i 直接修改源文件
-e 可指定多个处理动作
-r 支持扩展表达式
{} 可组合多个命令,以;分隔
-f 使用sed脚本
定址符:
p 打印行
d 删除行
s 字符串替换
1 对第1行处理
1,3 对第1到3行处理
1,+3 对第1行后面3行处理
1~2 对1,3,5,7……行处理
1,$ 对1行到最后1行处理
/aa/,/bb/ 对a行到b行处理
/aaa/,9 对a行到第9行,若前9行没有,会显示后9行匹配的行
举例子:(注意:sed增删改如果不加 -i 选项的话只是预览模式,并没有真的增删改)
增: i 行前插入 a 行后插入 sed ‘2ixx‘ m.txt 在第2行前插入行xx sed ‘3,6ixx‘ m.txt 在第3-6行每行前插入xx sed ‘2axx‘ m.txt 在第2行后插入xx sed ‘/^yy/axx‘ m.txt 在yy开头的行后插入xx
删:
sed ‘3,5d‘ a.txt 删除第3到5行
sed ‘/xml/d‘ a.txt 删除所有包含xml的行
sed ‘/xml/!d‘ a.txt 删除不包含xml的行
sed ‘/^xml/d‘ a.txt 删除以xml开头的行
sed ‘$d‘ a.txt 删除最后1行
sed ‘/^$/d‘ a.txt 删除所有空行
sed ‘/^$/{n;/^$/d}‘ a.txt 删除重复空行,连续两个空行只保留一个
sed -r‘/a|b/d‘ a.txt 删除a或b的行
sed ‘2,~2d‘ a.txt 删除2行到2的倍数行
改:
c 行替换
s 字符串替换
sed ‘2cxx‘ m.txt 第2行替换成xx
sed ‘3,6cxx‘ m.txt 第3到6行替换成1行xx
sed -n ‘2cxx\nyy‘ m.txt 第2行替换成xx并换行yy(\n换行符==强制换行)
sed -e ‘3cxx‘ -e ‘6cxx‘ m.txt 第3行和第6行替换成xx
sed ‘s#a#&s#g‘ a.txt 所有的a都替换成as,&代表查找串(类似{})
sed ‘s#a##g‘ a.txt 删除所有行的a
sed ‘4,7s/^/#/‘ a.txt 4到7行加#号
sed ‘4,7s/^#//‘ a.txt 4到7行去掉#号
sed ‘s/a/B/ig‘ a.txt 所有行的a替换成B(不区分大小写)
查:
sed –n ’20,30p’ b.txt 打印20到30行
sed -n ‘3p;6p‘ a.txt 打印第3和6行
sed -n ‘3,+6p‘ a.txt 打印第3行及其后6行
sed -n ‘/^bin/p‘ a.txt 打印以bin开头的行
sed -n ‘p;n‘ a.txt 打印奇数行,n表示读下一行(隔行)
sed -n ‘n;p‘ a.txt 打印偶数行,n表示读下一行(隔行)
sed -n ‘8,${n;p}‘ a.txt 打印8行到末尾所有的偶数行
sed -n ‘$=‘ a.txt 打印文件的行数
sed -n ‘/a/{=;p} ‘ b.txt 显示行号
sed -n l aaa.jpg 打印不可见字符
报告生成器,格式化文本输出,有多种版本:New awk(nawk),GNU awk( gawk)
awk [options] ‘program‘ file
1、常用命令选项
-F 指定分隔符,默认空格或Tab键
-f 调用awk脚本
-v 调用外部shell变量
2、awk内置变量
$1..$n 指定分隔符号对应的值
$0 当前行的内容
$NF 最后一列
NF 指定分隔符号后,行的列数
NR 当前行的行号
FS 保存或设置字段分隔符
FNR 保存当前文件的行数
FILENAME 保存当前的文件名
ENVIRON 调用shell环境变量
awk ‘{print $0}‘ a.txt #打印文件所有内容
awk ‘{print $1,$2}‘ a.txt #打印第1列和第2列的内容
awk -F: ‘{print $1}‘ a.txt #以:为分隔符并打印第1列的内容
awk -F, ‘{print NF,NR}‘ a.txt #以,为分隔符并打印行号和列数
3、awk自定义变量
echo 111 | awk ‘{a=10;b="jim";print a,b}‘
x=100;echo 111 | awk -v a=$x ‘{print a}‘
4、awk调用shell系统环境变量
ENVIRON (数组类型的内置变量)
ENVIRON["系统环境变量名"]
echo 111 | awk ‘{print ENVIRON["USER"]}‘
5、awk处理数据的顺序
行前处理 BEGIN{ }
逐行处理 { }
行后处理 END{ }
awk ‘BEGIN{x=0}/bash/{x++} END{print x}‘ /etc/passwd #统计使用bash的用户个数
head /etc/passwd|awk -F ":" ‘{print $1"\t",$3,"\t"$6}‘|sed ‘1i用户名 uid 家目录‘
head /etc/passwd|awk ‘BEGIN{FS=":";print "用户名\tuid\t家目录"}{print $1"\t",$3"\t",$6}‘
6、正则表达式
/正则/ 匹配正则(行)
~/正则/ 匹配正则(列)
!~/正则/ 不匹配
awk ‘$0 ~ /root/{print $0}‘ /etc/passwd
awk ‘$0 !~ /root/{print $0}‘ /etc/passwd
awk -F ":" ‘/^ro/{print}‘ /etc/passwd
awk -F ":" ‘$1 ~ /[0-9]/{print $1,$6}‘ /etc/passwd
7、数值比较
awk -F ":" ‘$3 == 0 {print $0}‘ /etc/passwd
awk -F ":" ‘$3 != 0 {print $0}‘ /etc/passwd
awk -F ":" ‘$1 == "root" {print $0}‘ /etc/passwd
8、逻辑比较(多个条件)
逻辑与 && 多个条件同时成立
逻辑或 || 多个条件有一个成立
逻辑非 ! 取反
awk -F ":" ‘$7=="/bin/bash" && $3<500{print $0}‘ /etc/passwd
awk -F ":" ‘$7=="/bin/bash" || $3<500{print $0}‘ /etc/passwd
9、awk运算符号
三元运算符的形式:[结果=条件? 结果1:结果2]或 [条件?表达式1:表达式2]
awk ‘BEGIN{a="b";print a=="c"?"ok":"err"}‘ #三元运算符
awk ‘FNR%2 == 0 {print FNR,$0}‘ /etc/passwd #输出文件中的偶数行
awk ‘FNR%2 != 0 {print FNR,$0}‘ /etc/passwd #输出文件中的奇数行
awk -F ":" ‘$3<500 {i++}END{print i}‘ /etc/passwd #统计uid号小于500的用户个数
awk -F ":" ‘$3>=500 {i++}END{print i}‘ /etc/passwd #统计普通用户的个数
awk -F ":" ‘$7=="/sbin/nologin"{i++}END{print i}‘ /etc/passwd #统计有多少用户不能登录系统
seq 1 10 | awk ‘$0%2 == 0 {print $0;i++}END{print i}‘ #输出1到10之间的偶数,并统计偶数的个数
seq 1 10 | awk ‘$0%7 == 0 || $0 ~ /7/{print $0}‘ #输出1到10之间,7倍数或含7的数
10、awk流程控制
单分支 if (条件表达式) { 动作 }
awk -F ":" ‘{ if($3<500)i++ } END{print i}‘ /etc/passwd
双分支 if (条件表达式) { 动作 } else { 动作 }
awk -F ":" ‘{ if($3<500){i++}else{j++} }END{print i,j}‘ /etc/passwd
多分支 if( 条件1 ){ 指令 } else if( 条件2 ){指令} else{指令N}
awk -F ":" ‘{if ($7=="/bin/bash"){i++}else if($7=="/sbin/nologin"){j++}else{z++}}END{print i,j,z}‘ /etc/passwd
11、for循环结构
for( 赋初值;条件;步长 ){ 循环体 }
break #结束当前的循环体
continue #中止本次循环,开始下一次循环
next #跳过当前行,读入下一行文本开始处理
exit #结束文本读入,转到END{}执行,没有END,直接退出awk
awk ‘BEGIN{for(i=1;i<=5;i++){print i} }‘
awk ‘BEGIN{for(i=1;i<=5;i++){ip[i]="1.1.1."i};for(x=1;x<=5;x++){print ip[x]}}‘
awk ‘BEGIN{for(x=1;x<=5;x++){if(x==3){continue};print x}}‘
awk ‘FNR==3{exit}{print FNR,$0}‘ a.txt
awk -F ":" ‘$1~/a/{next}{print FNR,$1}‘ /etc/passwd
awk ‘NF<2{next}{print}‘ a.txt #输出2列以上的行,跳过空行及1列的行
12、while循环结构
while (条件判断){ 循环体 }
do { 循环体 }while(条件判断),先循环再判断条件,无论条件是否成立,都会循环一次
awk ‘BEGIN{i=1;while(i<=5){print "a"i;i++} }‘
awk ‘BEGIN{do { print "a "x" b";x++}while(x<=5)}‘
awk ‘BEGIN{x=1; do{print "a "x" b";x++}while(x<=5)} ‘
awk ‘BEGIN{x=1;while(x<=5){if(x==3){break};print x;x++}}‘
awk ‘BEGIN{x=1;while(x<=5){if(x==3){x++;continue};print x;x++}}‘
13、awk数组
awk ‘BEGIN{a[0]="jim";a[1]=29;print a[0],a[1]}‘
head /etc/passwd | awk -F ":" ‘{a[FNR]=$1;print a[FNR]}‘
awk ‘{a[i]++ }END{print a[i] }‘ /etc/passwd
awk ‘BEGIN{ for(i=1;i<=3;i++){a[i]="8"i;print a[i]}}‘
awk -F ":" ‘$3<=2{a[$1]=$3}END{print a["root"]}‘ /etc/passwd
awk -F ":" ‘{a[$3]=$1}END{for(i=0;i<=3;i++){print i,a[i]}}‘ /etc/passwd(有序)
awk -F ":" ‘NR<=3{a[$1]=$3}END{for(i in a){print i,a[i]}}‘ /etc/passwd (无序)
awk ‘!a[$0]++‘ /etc/passwd (去除重复行)
awk数组下标默认从1开始,元素的值可以是"空字符串"
14、awk应用
1)统计访问网站服务器的IP和次数
awk ‘{ip[$1]++}END{for(i in ip){print i,ip[i]}}‘ access_log
2)统计日志中访问最多的10个IP
awk ‘{a[$1]++}END{for(i in a)print a[i],i|"sort -k1 -nr|head -n10"}‘ access.log
awk ‘{print $1}‘ access.log |sort |uniq -c |sort -k1 -nr |head -n10
3)统计日志中访问大于100次的IP
awk ‘{a[$1]++}END{for(i in a){if(a[i]>100)print i,a[i]}}‘ access.log
4)统计2016年4月9日一天内访问最多的10个IP
awk ‘$4>="00:00:01" && $4<="23:59:59" {a[$1]++}END{for(i in a)print a[i],i}‘ access.log |sort -r|head -10
sed -n ‘/00:00:01/,/23:59:59/p‘ access.log| awk ‘{print $1}‘ |sort |uniq -c |sort -r |head -10
5)统计当前时间前一分钟的访问数
day=$(date -d ‘-1 minute‘ +%H:%M);awk -va=$day ‘$0~a{c++}END{print a,c}‘ access.log
grep -c $(date -d ‘-1 minute‘ +%H:%M) access.log
6)统计每个URL访问内容的总大小($body_bytes_sent)
awk ‘{a[$7]++;size[$7]+=$10}END{for(i in a)print a[i],size[i],i}‘ access.log
7)统计每个IP访问状态码数量
awk ‘{a[$1"\t"$9]++}END{for(i in a)print i,a[i]}‘ access.log
8)统计访问状态码为404的IP及出现次数
awk ‘{if($9~/404/)a[$1"\t"$9]++}END{for(i in a)print i,a[i]}‘ access.log
9)统计下面文件里单词出现的次数并排序
sed -r ‘s#[^a-Z]+# #g‘ /etc/passwd > /tmp/tongji.txt 创建文件
sed ‘s# #\n#g‘ tongji.txt|sort |uniq -c
tr " " "\n" < tongji.txt|sort |uniq -c
egrep -o "[a-z0-9]+" tongji.txt|sort |uniq -c
xargs -n1 <tongji.txt|sort |uniq -c
awk ‘BEGIN{RS=" "}{print $0}‘ tongji.txt|sort |uniq -c
10)显示行号
cat -n tongji.txt (包括空行)
cat -b tongji.txt (不包括空行)
nl -ba tongji.txt (包括空行)
nl -bt tongji.txt (不包括空行)
grep -n "." tongji.txt (包括空行不显示)
grep -n ".*" tongji.txt (包括空行并显示)
sed -n ‘=;p‘ tongji.txt (包括空行)
awk ‘{print NR":"$0}‘ tongji.txt (包括空行)
wc -l tongji.txt (包括空行)
less -N tongji.txt (包括空行)原文:https://www.cnblogs.com/chenbin93/p/13430803.html