文本处理工具awk常用命令

awk 其实是一门编程语言,它,支持条件判断、数组、循环等功能,我们可以把它理解成一个脚本语言解释器
它与grep、sed被linux称为"三剑客"
每个都有它的特长
grep 更适合单纯的去查找或者匹配文本
sed 更适合编辑匹配到的文本
awk 更适合格式化文本,对文本进行较复杂格式处理

成都创新互联是网站建设专家,致力于互联网品牌建设与网络营销,专业领域包括网站制作、网站设计、电商网站制作开发、微信小程序开发、微信营销、系统平台开发,与其他网站设计及系统开发公司不同,我们的整合解决方案结合了恒基网络品牌建设经验和互联网整合营销的理念,并将策略和执行紧密结合,且不断评估并优化我们的方案,为客户提供全方位的互联网品牌整合方案!

一、AWK基础
awk的基本用法
格式
awk 动作 文件名/文件名/awk/动作

如果不指定任何参数直接使用awk
格式是这样的
awk '{print}' 文件
直接回输出整个文件,相当于shell中的cat命令
示例

[root@zhaocheng ~]# awk '{print}' echo.sh 
#!/bin/bash
echo  "shucai"\b"niunai"

取free -m文件的第3列,这样取的话,我们可以直接去使用free -m 先让它输出,然后通过管道再去取它的第三列,像取第三列的话,其实中间还是有分隔符的,也就是空格,不指定分隔符,默认将空格作为分隔符了

[root@zhaocheng ~]# free -m |awk '{print $3}' 
free
115
0

也可以去取多个列,以,分开,比如还是取free -m,取它的第2,3,4列

[root@zhaocheng ~]# free -m |awk '{print $2,$3,$4}'
used free shared
1838 116 339
0 0 0

另外awk还支持对文本的处理,添加字符串,像这个/etc/passwd文件中就是看起来是有列的,但是awk默认不加-F是先按空格去提取的,而这个没有所以添加了一个":"当作文本的分隔符
格式
'{print $1,"hello"}'
'{print $1,$2,"hello"}'
'{print $1,"net",$2,"hello"}'

[root@zhaocheng ~]# awk -F ":" '{print $1,$2,"hello"}' test 
root x hello
bin x hello
daemon x hello
adm x hello
lp x hello
sync x hello
shutdown x hello
halt x hello

[root@zhaocheng ~]# awk -F ":" '{print $1,"net",$2,"hello"}' test 
root net x hello
bin net x hello
daemon net x hello
adm net x hello
lp net x hello
sync net x hello
shutdown net x hello
halt net x hello

而它的格式也是'{print $1}'中间不能加引号,不然会当成普通字符给输出

[root@zhaocheng ~]# awk -F ":" '{print "$1"}' test 
$1
$1
$1
$1
$1
$1
$1
$1
[root@zhaocheng ~]# awk -F ":" '{print '$1'}' test 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt

比如打印文件,也就是相当于cat命令一样去用了,这里awk给出两个用法,第一个就是可以使用awk '{print $0}'或者可以使用awk '{print}',这两种都可以打印出来

[root@zhaocheng ~]# echo "Learn awk to improve your Linux skills" |awk '{print}'
Learn awk to improve your Linux skills
[root@zhaocheng ~]# echo "Learn awk to improve your Linux skills" |awk '{print $0}'
Learn awk to improve your Linux skills

而$0表示显示整行,$NF表示当前行分隔后的最后一列($0和$NF均为内置变量)
每行的倒数第二列都可以写成$(NF-1)

[root@zhaocheng ~]# awk -F: '{print $(NF-1)}' test 
/root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
/sbin
/sbin
[root@zhaocheng ~]# awk -F: '{print $NF}' test 
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt

awk包含了两种特殊的模式:BEGIN和END
BEGIN模式是指定了处理文本之前需要执行的操作
END模式指定了处理完所有行之后所需要执行的操作

这个BEGIN可以看到,即使我们后面指定了输出源,但是它还是只打印了前面的字符,这也就是BEGIN的模式

[root@zhaocheng ~]# awk 'BEGIN{print "one","two"}'
one 

[root@zhaocheng ~]# cat filetest 
root:$1$dDTFylQ3$.vTZKpm7mrra9WMsxvBfW.:18241:0:99999:7
bin:*:17834:0:99999:7:dad
lp:*:17834:0:99999:7ada
sync:*:17834:0:99999:7:::gg
shutdown:*:17834:0:99999:7::da
halt:*:17834:0:99999:7::fsda
nginx:!!:18289::::::daaf
rabbitmq:!!:18297:::::dada

二、AWK的分隔符
awk的分隔符的使用,这里可以使用多种方法
-F 以什么为分隔符,来取第二列和第三列,-F:,-F"",-F''三种办法都可以使用去取这个值

[root@zhaocheng ~]# awk -F: '{print $2,$3}' test 
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7
[root@zhaocheng ~]# awk -F ":" '{print $2,$3}' test 
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7
[root@zhaocheng ~]# awk -F ':' '{print $2,$3}' test 
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7

除了-F选项,还能通过设置内部变量的方式,指定awk的输入分隔符,awk内置变量FS可以用于指定输入分隔符,但在使用变量时,需要使用-v选项,这里使用"",''都可以

[root@zhaocheng ~]# awk -v FS=':' '{print $2,$3}' test 
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7
[root@zhaocheng ~]# awk -v FS=":" '{print $2,$3}' test 
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7

awk的语法如下
**awk [选项] '模式{动作}' file
而-F 就是选项的一种,一般用于指定分隔符 -v也是选项的一种,用于设置变量的值

而AWK的分隔符又分为输入分隔符和输出分隔符

输入分隔符:也就是在输入命令的时候以:,#为分隔符的时候这就是我们输入的分隔符
输出分隔符:也就是当我们以#为分隔符的时候,输出的结果会有空格隔开,这就是我们的输出分隔符,实际上没有输出出来

当然我们也可以将我们的输出分隔符以awk的内置变量OFS进行输出出来显示,使用变量的时候需要加-v选项,OFS相当于以空格为分隔符了**

[root@zhaocheng ~]# cat test1
aaa bbb ooo
cccc   dddd   eeee
fffff  ggggg hhhhh
kkkkk pppppp ssssss
[root@zhaocheng ~]# awk -v OFS="********" '{print $2,$3}' test1
bbb********ooo
dddd********eeee
ggggg********hhhhh
pppppp********ssssss

如果想以中间的符号为分隔符可以以FS=":"当分隔符来,同时指定输入分隔符和输出分隔符

[root@zhaocheng ~]# cat test
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
[root@zhaocheng ~]# awk -v FS=":" -v OFS="********" '{print $2,$3}' test
x********0
x********1
x********2
x********3
x********4
x********5
x********6
x********7

刚才使用的是输出分隔符想让中间的空格用指定输出隔开,如果不使用中间的符号进行隔开,直接进行合并的话,只需要将$1 $2分开,不加,号,一个是连接一起显示,一个是以分隔符进行显示

[root@zhaocheng ~]# awk '{print $1 $2}' test1
aaabbb
ccccdddd
fffffggggg
kkkkkpppppp
[root@zhaocheng ~]# awk '{print $1,$2}' test1
aaa bbb
cccc dddd
fffff ggggg
kkkkk pppppp

三、AWK的变量
对于awk来说“变量”又分为‘内置变量和’自定义变量“ ,”输入分隔符FS,和输出分隔符“OFS都属于内置变量

awk的常用内置变量以及作用
FS:输入字段分隔符,默认为空白字符
OFS:输出字段分隔符,默认为空白字符
RS:输入记录分隔(输入换行符)指定输入时的换行符
ORS:输入记录分隔符(输出换行符),输出时用指定符号代替换行符
NF:当前行的字段的个数(即当前行被分隔成了几列),字段数量
NR:行号,当前处理的文本行的行号
FNR:各文件分别计数的行号
FILENAME:当前文件名
ARGC:命令行的参数的个数
ARGV: 数组,保存的是命令行所给定的各参数

刚才的FS和OFS都用过了,FS是输入分隔符,OFS是输出分隔符,默认都是空白字符,比如FS以什么为分隔符-v FS=":"以:为分隔符,输出的时候一般不加后门的OFS显示以空格分隔,如果在输出格式添加,需要指定-v OFS=""将空格替换成来展示

内置变量NR、NF
刚才说到NR,其实就是当前文本的行号,一共几行
NF就是一行中有几列,一般以空格为分隔符
这里一共4列,使用NR直接显示了行号

[root@zhaocheng ~]# cat test1
aaa bbb ooo
cccc   dddd   eeee
fffff  ggggg hhhhh
kkkkk pppppp ssssss
[root@zhaocheng ~]# awk '{print NR}' test1
1
2
3
4

这里每行中有3列,所以使用NF就能统计出有多少列

[root@zhaocheng ~]# awk '{print NR,NF}' test1
1 3
2 3
3 3
4 3

统计test文件有多少行,使用行号进行排序
可以使用awk的{print $0 NR}'

[root@zhaocheng ~]# awk '{print NR,$0 }' test 
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt

或者使用cat -n 也是统计行号的

[root@zhaocheng ~]# awk '{print}' test |cat -n
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     6  sync:x:5:0:sync:/sbin:/bin/sync
     7  shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     8  halt:x:7:0:halt:/sbin:/sbin/halt

在bash语法中一般使用变量比如打印第一行需要$1,第二行$2,那么在awk中,不管使用内置变量还是自定义变量都不需要加$

内置变量FNR

这个一般是处理多个文件的同时来记录行号的内置变量,如果匹配多个文件的话,使用NR来记录行号只会按顺序直接排列,使用FNR会分开排列

[root@zhaocheng ~]# awk '{print NR,$0}' test test1
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 aaa bbb ooo
10 cccc   dddd   eeee
11 fffff  ggggg hhhhh
12 kkkkk pppppp ssssss
[root@zhaocheng ~]# awk '{print FNR,$0}' test test1
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
1 aaa bbb ooo
2 cccc   dddd   eeee
3 fffff  ggggg hhhhh
4 kkkkk pppppp ssssss

内置变量RS
RS是输入行分隔符,如果不指定,默认的行分隔符就是我们理解的回车换行

[root@zhaocheng ~]# awk -v RS=" " '{print NR,$0}' test1
1 aaa
2 bbb
3 ooo
cccc
4 dddd
5 eeee
fffff
6 ggggg
7 hhhhh
kkkkk
8 pppppp
9 ssssss

内置变量ORS
这个和ORS的换行符差不多,只不过在指定输出行分隔符+++的时候另换一行

[root@zhaocheng ~]# awk -v ORS="++++" '{print NR,$0}' test1
1 aaa bbb ooo++++2 cccc dddd eeee++++3 fffff ggggg hhhhh++++4 kkkkk pppppp ssssss++++[root@zhaocheng ~]# 

内置变量FILENAME
FILENAME这个内置变量从字面上,可以看出是什么意思,就是显示文件名,使用指定多文件的FNR,统计行号,在前面并打印出这个文件的名称

[root@zhaocheng ~]# awk '{print FILENAME,FNR,$0}' test1 test
test1 1 aaa bbb ooo
test1 2 cccc dddd eeee
test1 3 fffff ggggg hhhhh
test1 4 kkkkk pppppp ssssss
test 1 root:x:0:0:root:/root:/bin/bash
test 2 bin:x:1:1:bin:/bin:/sbin/nologin
test 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
test 4 adm:x:3:4:adm:/var/adm:/sbin/nologin
test 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
test 6 sync:x:5:0:sync:/sbin:/bin/sync
test 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
test 8 halt:x:7:0:halt:/sbin:/sbin/halt

内置变量ARGV与ARGC
ARGV内置变量表示的是一个数组,这个数组中保存的是命令行所给定的参数

[root@zhaocheng ~]# awk 'BEGIN{print "aaa"}' test test1
aaa
[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[1]}' test test1
aaa test
[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[2]}' test test1
aaa test1
[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[1],ARGV[2]}' test test1
aaa test test1

从上面看出ARGV内置变量表示的是一个数组,第一个数组就是test,第二个就是test1这个文件,而ARGV[0]这个就是我们本身的内置变量awk

[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[0],ARGV[1],ARGV[2]}' test test1
aaa awk test test1

而这个ARGC就是统计整个变量的数量

[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[0],ARGV[1],ARGV[2],ARGC}' test test1
aaa awk test test1 3

自定义变量
自定义变量就是给用户定义变量

[root@zhaocheng ~]# awk -v www="1234" 'BEGIN{print www}'
1234
[root@zhaocheng ~]# awk 'BEGIN{www="1234" ; print www}'
1234
一次性定义多个变量
[root@zhaocheng ~]# awk 'BEGIN{www="1234"; baidu="4567" ; print www , baidu}'
1234 4567

四、AWK格式化
对比print 和printf的区别,可以看出print 可以取$1的内容,而printf不会输出换行符,默认会将文本输出在一行里面

[root@zhaocheng ~]# awk '{print $1}' test1
aaa
cccc
fffff
kkkkk
[root@zhaocheng ~]# awk '{printf $1}' test1
aaaccccfffffkkkkk[root@zhaocheng ~]# 

如果使用printf的格式替换符的话也可以将printf的格式打印出来

[root@zhaocheng ~]# awk '{printf "%s\n" ,$1}' test1
aaa
cccc
fffff
kkkkk

使用printf用法的是时候需要格式与列需要用逗号隔开,另外就是打印字符串的时候,可以通过\n,或者%s\n来替换

[root@zhaocheng ~]# printf  "helloya\n"
helloya
[root@zhaocheng ~]# printf "%s\n" helloya
helloya

在使用awk中的printf动作的时候需要注意点
1)使用printf动作输出的文本不会换行,如果需要换行,可以在对应的格式替换符后加入\n进行转义
2)使用printf动作时,指定的格式与被格式化的文本之间,需要用逗号隔开
3)使用printf动作时,格式中的格式替换符必须与被格式化的文本 一一对应

可以利用格式替换符对文本中的每一列进行格式化
针对空格进行使用awk与printf打印格式化,默认不使用输入分隔符就是空格

[root@zhaocheng ~]# cat test1
aaa bbb ooo
cccc dddd eeee
fffff ggggg hhhhh
kkkkk pppppp ssssss
[root@zhaocheng ~]# awk '{printf "%s\n",$1}' test1
aaa
cccc
fffff
kkkkk
[root@zhaocheng ~]# awk '{printf "第一列 %s\n",$1}' test1
第一列 aaa
第一列 cccc
第一列 fffff
第一列 kkkkk

[root@zhaocheng ~]# awk '{printf " 第一列 %s 第二列 %s\n" ,$1,$2}' test1
 第一列 aaa 第二列 bbb
 第一列 cccc 第二列 dddd
 第一列 fffff 第二列 ggggg
 第一列 kkkkk 第二列 pppppp
[root@zhaocheng ~]# awk '{printf  " 第二列 %s\n",$2}' test1
 第二列 bbb
 第二列 dddd
 第二列 ggggg
 第二列 pppppp
[root@zhaocheng ~]# awk '{printf  " 第三列 %s\n",$3}' test1
 第三列 ooo
 第三列 eeee
 第三列 hhhhh
 第三列 ssssss
[root@zhaocheng ~]# awk '{printf  "第一列 %s  第三列 %s\n",$1,$3}' test1
第一列 aaa  第三列 ooo
第一列 cccc  第三列 eeee
第一列 fffff  第三列 hhhhh
第一列 kkkkk  第三列 ssssss
[root@zhaocheng ~]# awk '{printf  "第一列 %s 第二列 %s 第三列 %s\n",$1,$2,$3}' test1
第一列 aaa 第二列 bbb 第三列 ooo
第一列 cccc 第二列 dddd 第三列 eeee
第一列 fffff 第二列 ggggg 第三列 hhhhh
第一列 kkkkk 第二列 pppppp 第三列 ssssss

对于有分隔符的#来实现格式化

[root@zhaocheng ~]# cat test2
aaa#bbb#ooo
cccc#dddd#eeee
fffff#ggggg#hhhhh
kkkkk#pppppp#ssssss

普通使用 -v FS输入分隔符,以#分隔

[root@zhaocheng ~]# awk -v FS="#" '{print $1,$2}' test2
aaa bbb
cccc dddd
fffff ggggg
kkkkk pppppp


普通使用-v OFS 输出分隔符

[root@zhaocheng ~]# awk -v FS="#" -v OFS="####" '{print $1,$2}' test2
aaa####bbb
cccc####dddd
fffff####ggggg
kkkkk####pppppp

使用printf格式化输出

[root@zhaocheng ~]# awk -v FS="#" '{printf "第一列 %s\n" ,$1}' test2
第一列 aaa
第一列 cccc
第一列 fffff
第一列 kkkkk
[root@zhaocheng ~]# awk -v FS="#" '{printf "第一列 %s 第二列 %s \n" ,$1,$2}' test2
第一列 aaa 第二列 bbb 
第一列 cccc 第二列 dddd 
第一列 fffff 第二列 ggggg 
第一列 kkkkk 第二列 pppppp

结合BEGIN处理文本之前需要执行的操作,与printf结合使用

[root@zhaocheng ~]# awk 'BEGIN{printf "%1s\t %s\n" ,"用户名称","用户ID"}' test1
用户名称         用户ID
[root@zhaocheng ~]# awk 'BEGIN{printf "%1s\t %s\n" ,"用户名称","用户ID"} {printf "%1s\t %10s\n" , $1,$2}' test1
用户名称         用户ID
aaa             bbb
cccc           dddd
fffff         ggggg
kkkkk        pppppp

以#为分隔符进行格式化文本

[root@zhaocheng ~]# awk -v FS="#" 'BEGIN{printf "%1s\t %s\n" ,"用户名称","用户ID"} {printf "%1s\t %10s\n" , $1,$2}' test2
用户名称         用户ID
aaa             bbb
cccc           dddd
fffff         ggggg
kkkkk        pppppp

五、AWK模式(pattern)

对于awk使用语法
awk [options] 'Pattern {Action}' file1 file2 ...

awk -v FS=":" 'BEGIN{print/printf %1s\t %s\n","x x x", "xxxx"} {xxx}' file 
对于options(选项),使用过 -F选项,也使用过 -v选项
对于Acation(动作),使用过print与printf 
对于Pattern(模式),使用过BEGIN模式与END模式
下面熟悉一个awk的条件,也就是awk会先处理完当前行,在处理下一行,如果我们不指定任何“条件”,awk会一行一行的处理文本中的每一行,如果我们指定来条件,只有满足条件的的行才会被处理,不满足条件的行就不会被处理,这就是awk中的模式

其实在当awk进行逐行处理的时候,会把pattern(模式)作为条件,判断将要被处理的行是否满足条件,是否能跟模式想匹配,如果匹配就处理,如果不匹配,则不进行处理

NF==4之前我们使用NF的时候是统计有多少列每行,NF==4也就是有4列的行,然后打印出来

[root@zhaocheng ~]# awk 'NF==4 {print}' test1
fffff ggggg hhhhh bbbbb
[root@zhaocheng ~]# awk 'NF==5 {print}' test1
kkkkk pppppp ssssss xxxxxx   mmmmmmmm

文本处理工具awk常用命令

这就是awk使用到的关系表达式,比如==,<,>,<=,>=,也就是得到的结果为真时,则满足条件,与指定模式想匹配,满足时就会执行相应的动作。

示例

[root@zhaocheng ~]# cat test1
aaa bbb ooo
cccc dddd eeee
fffff ggggg hhhhh bbbbb
kkkkk pppppp ssssss xxxxxx   mmmmmmmm
大于4列的行
[root@zhaocheng ~]# awk 'NF>4 {print $0}' test1
kkkkk pppppp ssssss xxxxxx   mmmmmmmm
大于等于4列的行
[root@zhaocheng ~]# awk 'NF>=4 {print $0}' test1
fffff ggggg hhhhh bbbbb
kkkkk pppppp ssssss xxxxxx   mmmmmmmm
小于等于4列的行
[root@zhaocheng ~]# awk 'NF<=4 {print $0}' test1
aaa bbb ooo
cccc dddd eeee
fffff ggggg hhhhh bbbbb

实际上awk有四种pattern模式
第一种就是BEGIN,表示在开始处理文本之前,需要执行的操作
第二种时END模式,表示将所有行都处理完毕后,需要执行的操作
第三种就是关系运算模式,刚才我们用到的NF==xx
第四种就是空模式,就是相当于awk '{print $0}' file,空模式会匹配文本中每一行,所以每一行都满足条件,每一行都会执行动作

熟悉一下END模式,ENGIN就是开始先处理什么,END就是最后处理什么
示例

[root@zhaocheng ~]# awk 'BEGIN{print "开始","开始"} {print $1,$2} END{print "结束","结束"}' test1
开始 开始
aaa bbb
cccc dddd
fffff ggggg
kkkkk pppppp
结束 结束

六、AWK模式(Pattern) 正则表达式
awk的另外两种常用模式,正则模式与行范围模式

正则模式:顾名思义与正则表达式有关,模式可以理解为条件,当不指定模式时,文本中的每一行都会执行对应的动作,当有被模式匹配到的,符合条件的行才会执行相应的动作,正则模式可以理解为,把正则表达式当作条件,能与正则匹配的行,就算满足条件,满足条件的行才会执行相应的动作,不能被正则匹配到的行,则不会执行对应的动作

使用grep/awk找出/etc/passwd山以ftp开头的行
[root@zhaocheng ~]# grep "^ftp" /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@zhaocheng ~]# awk '/^ftp/{print $0}' /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

不管是使用grep命令,还是使用awk命令,都使用了相同的正则表达式^ftp
唯一区别就是,在grep命令中,直接使用了正则表达式,而在awk中正则表达式被放入到了两个斜线中

grep "正则表达式" /etc/passwd
awk '/正则表达式'/{print $0}' /etc/passwd

而awk的优势就是格式化输出

[root@zhaocheng ~]# awk -v FS=":" 'BEGIN{printf "%-10s%-10s\n","用户名称","用户ID"} /^ftp/{printf "%-10s\t%-10s\n",$1,$3}' /etc/passwd
用户名称      用户ID      
ftp             14  


使用grep的时候利用正则表达式可以$就可以输出,使用awk输出的话,就需要添加转义符

[root@zhaocheng ~]# grep "/bin/bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@zhaocheng ~]# awk '/\/bin\/bash$/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash

awk的行匹配模式

[root@zhaocheng ~]# awk '/helm/{print $0}' test6
helm.org

匹配行语法
awk '/正则表达式/{动作}' / file
awk '/正则1/,/正则2/{动作}' / file


可以打印大于=3行,小于等于4行的

[root@zhaocheng ~]# awk 'NR>=3 && NR<=4 {print $0}' test6
rabbitmq.com
zookpeer.com

分享题目:文本处理工具awk常用命令
文章源于:http://cdiso.cn/article/gdppjj.html

其他资讯