Awk,sed,grep三剑客
Grep合适单纯的查找或者匹配文本
Sed合适编辑匹配到的文本
Awk更合适格式化,对文本进行比较复杂的处理
Awk语法 awk [options] ‘program’ file1,file2........
# awk ‘条件1{动作1} 条件2{动作2}…’ 文件名
条件(Pattern):
一般使用关系表达式作为条件
x > 10 判断变量 x是否大于10
x>=10 大于等于
x<=10 小于等于
动作(Action):
格式化输出
流程控制语句
Awk基本了解篇
1先从简单的一个打印动作来初步了解awk
创建测试数据
[[email protected] tmp]# echo test >testd
[[email protected] tmp]# cat testd
test
[[email protected] tmp]# awk ‘{print}‘ testd
Test
场景2
[[email protected] tmp]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda3 18375548 3566396 13875728 21% /
tmpfs 502204 0 502204 0% /dev/shm
/dev/sda1 198337 29662 158435 16% /boot
打印第五列
[[email protected] tmp]# df |awk ‘{print $5}‘
Use%
21%
0%
16%
一次打印多列,打印第一列和第五列
[[email protected] tmp]# df |awk ‘{print $1,$5}‘
Filesystem Use%
/dev/sda3 21%
tmpfs 0%
/dev/sda1 16%
[[email protected] tmp]# df |grep "sda3" |awk ‘{print $1,$5}‘
/dev/sda3 21%
除了输出文本中的列,还可以加入自己的字段,将自己的字段和文件中的列结合起来,如
[[email protected] tmp]# cat >>testd <<eof
> lixunhuan
> afei
> shangguangjinghong
> wangliqin
> eof
[[email protected] tmp]# awk ‘{print $1,"welcome"}‘ testd
test welcome
lixunhuan welcome
afei welcome
shangguangjinghong welcome
wangliqin welcome
[[email protected] tmp]# cat testd
test 98
lixunhuan 100
afei 95
shangguangjinghong 86
wangliqin 100
[[email protected] tmp]# awk ‘{print "name:" $1,"socer:" $2}‘ testd
name:test socer:98
name:lixunhuan socer:100
name:afei socer:95
name:shangguangjinghong socer:86
name:wangliqin socer:100
输出整行两种方法,一是$0 ,而是什么都不加
[[email protected] tmp]# cat testd
test 98
lixunhuan 100
afei 95
shangguangjinghong 86
wangliqin 100
[[email protected] tmp]# awk ‘{print}‘ testd
test 98
lixunhuan 100
afei 95
shangguangjinghong 86
wangliqin 100
[[email protected] tmp]# awk ‘{print $0}‘ testd
test 98
lixunhuan 100
afei 95
shangguangjinghong 86
wangliqin 100
Awk是逐行处理的,刚才已经演示了最常用的动作print,
介绍一下特殊模式begin和end
Begin模式指定了处理文本之前所需要执行的操作
End模式指定了处理完所有行之后所需要执行的操作
[[email protected] tmp]# cat testd
test 98
lixunhuan 100
afei 95
shangguangjinghong 86
wangliqin 100
[[email protected] tmp]# awk ‘BEGIN {print "aa","bb"}‘ testd
aa bb
[[email protected] tmp]# awk ‘BEGIN {print "aa","bb"}‘
aa bb
经过试验发现,我们不需要输入任何文件来源,awk就直接输出信息了,因为begin模式表示,在处理指定文本之前,需要先执行begin模式中的指定操作,而上述试验我只是让他做出打印输出,这时候如果我们想要先执行begin之前的作用之外,再执行我们我们自定义执行的动作去操作文本,例如
[[email protected] tmp]# cat testd
test 98
lixunhuan 100
afei 95
shangguangjinghong 86
wangliqin 100
[[email protected] tmp]# awk ‘BEGIN{print "aa","bb"} {print $1,$2}‘ testd
aa bb
test 98
lixunhuan 100
afei 95
shangguangjinghong 86
wangliqin 100
End模式就是在处理完所有指定的文本后,需要执行的作用,通常我们可以结合begin和end模式一起使用
[[email protected] tmp]# awk ‘BEGIN{print "aa","bb"}{print $1,$2} END {print "cc","dd"}‘ testd
aa bb
test 98
lixunhuan 100
afei 95
shangguangjinghong 86
wangliqin 100
cc dd
返回结果中有没有那种表头,表内容,表尾的那种感觉,这就是awk对文本格式化的能力
Awk分隔符
Awk默认分隔符是空格,但是这样描述并不十分准确,awk的分隔符分为两种,输出分隔符和输入分隔符
输入分隔符:默认是空白字符(空格),默认是以空格为分隔符对每一行进行分隔,我们可以指定我们想要的分隔符来分隔 参数-F
[[email protected] tmp]# cat >>test <<eof
> abc##luliechu##iuy#dd
> 8u#liusheng#li#32
> eof
[[email protected] tmp]# cat test
abc##luliechu##iuy#dd
8u#liusheng#li#32
[[email protected] tmp]# awk -F# ‘{print $1,$2,$3}‘ test
abc luliechu
8u liusheng li
还可以设置内置变量FS来指定分隔符,需要使用-V选项 ,如 -v FS=’#’
[[email protected] tmp]# cat test
abc##luliechu##iuy#dd
8u#liusheng#li#32
[[email protected] tmp]# awk -F# ‘{print $1,$2,$3}‘ test
abc luliechu
8u liusheng li
[[email protected] tmp]# ^C
[[email protected] tmp]# awk -v FS=‘#‘ ‘{print $1,$2,$3}‘ test
abc luliechu
8u liusheng li
可以看出效果是一样的
输出分隔符:当我们要对处理完的文本进行输出的时候,以什么文本或符号作为分隔符
默认是空白字符(空格),我们可以用内置变量OFS来设定awk的输出分隔符,使用变量的时候都需要配合使用-v选项
[[email protected] tmp]# ls
public test test1.txt test2.txt test3.txt test4.txt test5.txt testd
[[email protected] tmp]# rm -f test test{1..5}.txt
[[email protected] tmp]# ls
public testd
[[email protected] tmp]# cat >>test <<eof
> luliechu 123
> lixunhuan 145
> afei 98
> eof
[[email protected] tmp]# awk -v OFS="+" ‘{print $1,$2}‘ test
luliechu+123
lixunhuan+145
afei+98
同时指定输入分隔符合输出分隔符
[[email protected] tmp]# cat >>test <<eof
> luliechu#123
> lixuhuan#150
> eof
[[email protected] tmp]# awk -v FS="#" -v OFS=‘成绩=‘ ‘{print $1,$2}‘ test
luliechu成绩=123
lixuhuan成绩=150
在输出的时候合并一起显示,将两列合并显示
[[email protected] tmp]# awk ‘{print $1$2}‘ test
luliechu#123
lixuhuan#150
Awk变量
Awk变量分为自定义变量和内置变量
常见自定义变量以及作用如下
FS 输出分隔符
OFS 输入分隔符
ORS 输出换行符
NF 当前行的字段的个数(当前行被分隔成了多少列)
NR 行号
FNR 各文件分别计数的行号
FILENAME 当前文件名
ARGC 命令行参数的个数
ARGV 数组
NR实例
[[email protected] tmp]# cat test
luliechu 123
lixunhuan 145
afei 98
luliechu#123
lixuhuan#150
[[email protected] tmp]# awk ‘{print NR}‘ test
1
2
3
4
5
NF实例 显示每一行的行号以及每一行对应有多少列
[[email protected] tmp]# cat test
luliechu 123
lixunhuan 145
afei 98
luliechu#123
lixuhuan#150
[[email protected] tmp]# awk ‘{print NR}‘ test
1
2
3
4
5
[[email protected] tmp]# awk ‘{print NR,NF}‘ test
1 2
2 2
3 2
4 1
5 1
添加行号输出
[[email protected] tmp]# awk ‘{print NR,$0}‘ test
1 luliechu 123
2 lixunhuan 145
3 afei 98
4 luliechu#123
5 lixuhuan#150
如果我们同时处理多个文件时候行号显示
[[email protected] tmp]# awk ‘{print NR,$0}‘ test test1
1 luliechu 123
2 lixunhuan 145
3 afei 98
4 luliechu#123
5 lixuhuan#150
6 昔在九江上
7 遥望九华峰
8 天河挂绿水
9 秀出九芙蓉
10 我欲一挥手
11 谁人可想从
从返回结果可以看出,如果使用NR显示行号,那么多个文件的所有行会按照顺序进行排序,如果我们要分别显示两个文件的行号,就需要用到内置变量FNR
[[email protected] tmp]# awk ‘{print FNR,$0}‘ test test1
1 luliechu 123
2 lixunhuan 145
3 afei 98
4 luliechu#123
5 lixuhuan#150
1 昔在九江上
2 遥望九华峰
3 天河挂绿水
4 秀出九芙蓉
5 我欲一挥手
6 谁人可想从
输入行分隔符RS,默认是回车换行
假入我想让他认为每次遇到一个#就换行
[[email protected] tmp]# cat test
luliechu 123
lixunhuan 145
afei 98
luliechu#123
lixuhuan#150
[[email protected] tmp]# sed -n 1,3d test
[[email protected] tmp]# sed -i 1,3d test
[[email protected] tmp]# cat test
luliechu#123
lixuhuan#150
[[email protected] tmp]# awk -v RS="#" ‘{print NR,$0}‘ test
1 luliechu
2 123
lixuhuan
3 150
输出行分隔符,也就是在它为我们换行后会加上我们需要的标识,默认是回车,是没有任何标识的
[[email protected] tmp]# cat test
luliechu#123
lixuhuan#150
[[email protected] tmp]# awk -v ORS="+" ‘{print NR,$0}‘ test
1 luliechu#123+2 lixuhuan#150+[[email protected] tmp]#
输入换行符和输出换行符同时演示 RS ORS
[[email protected] tmp]# awk -v RS="#" -v ORS="+" ‘{print NR,$0}‘ test
1 luliechu+2 123
lixuhuan+3 150
+[[email protected] tmp]# cat test
luliechu#123
lixuhuan#150
自定义变量案例
[[email protected] tmp]# awk ‘BEGIN {myname="luliechu" ; print myname}‘
Luliechu