Linux三剑客之awk命令
awk简介
awk其名称得⾃于它的创始⼈ Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓⽒的⾸个字母。实际上 AWK 的确拥有⾃⼰的语⾔: AWK 程序设计语⾔,三位创建者已将它正式定义为“样式扫描和处理语⾔”。它允许您创建简短的程序,这些程序读取输⼊⽂件、为数据排序、处理数据、对输⼊执⾏计算以及⽣成报表,还有⽆数其他的功能。
awk 是⼀种很棒的语⾔,它适合⽂本处理和报表⽣成,其语法较为常见,借鉴了某些语⾔的⼀些精华,如 C 语⾔等。在 linux 系统⽇常处理⼯作中,发挥很重要的作⽤,掌握了 awk将会使你的⼯作变的⾼⼤上。 awk 是三剑客的⽼⼤,利剑出鞘,必会不同凡响。
使⽤⽅法
awk '{pattern + action}' {filenames}
尽管操作可能会很复杂,但语法总是这样,其中 pattern 表⽰ AWK 在数据中查的内容,⽽ action 是在到匹配内容时所执⾏的⼀系列命令。花括号({})不需要在程序中始终出现,但它们⽤于根据特定的模式对⼀系列指令进⾏分组。 pattern就是要表⽰的正则表达式,⽤斜杠括起来。
awk语⾔的最基本功能是在⽂件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进⾏其他⽂本操作。完整的awk脚本通常⽤来格式化⽂本⽂件中的信息。
通常,awk是以⽂件的⼀⾏为处理单位的。awk每接收⽂件的⼀⾏,然后执⾏相应的命令,来处理⽂本。
awk 的原理
通过⼀个简短的命令,我们来了解其⼯作原理。
[root@Gin scripts]# awk '{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin .....................................................
[root@Gin scripts]# echo hhh|awk '{print "hello,world"}'
hello,world
[root@Gin scripts]# awk '{print "hiya"}' /etc/passwd
hiya
hiya
hiya
hiya
...............................................
你将会见到/etc/passwd ⽂件的内容出现在眼前。现在,解释 awk 做了些什么。调⽤ awk时,我们指定/etc/passwd 作为输⼊⽂件。执⾏ awk 时,它依次对/etc/passwd 中的每⼀⾏执⾏ print 命令。
所有输出都发送到 stdout,所得到的结果与执⾏ cat /etc/passwd 完全相同。
现在,解释{ print }代码块。在 awk 中,花括号⽤于将⼏块代码组合到⼀起,这⼀点类似于 C 语⾔。在代码块中只有⼀条 print 命令。在 awk 中,如果只出现 print 命令,那么将打印当前⾏的全部内容。
再次说明, awk 对输⼊⽂件中的每⼀⾏都执⾏这个脚本。
$ awk -F":" '{ print $1 }' /etc/passwd
$ awk -F":" '{ print $1 $3 }' /etc/passwd
$ awk -F":" '{ print $1 " " $3 }' /etc/passwd
$ awk -F":" '{ print "username: " $1 "\t\tuid:" $3" }' /etc/passwd
-F参数:指定分隔符,可指定⼀个或多个
print 后⾯做字符串的拼接
下⾯通过⼏实例来了解下awk的⼯作原理:
实例⼀:
只查看⽂件(100⾏)内第20到第30⾏的内容(企业⾯试)
实例⼀:只查看
[root@Gin scripts]# awk '{if(NR>=20 && NR<=30) print $1}'
20
21
22
23
24
25
26
27
28
29
30
实例⼆:已知⽂件内容为:
[root@Gin scripts]#
I am Poe,my qq is 33794712
请从该⽂件中过滤出'Poe'字符串与33794712,最后输出的结果为:Poe 33794712
[root@Gin scripts]# awk -F '[ ,]+' '{print $3" "$7}'
Poe 33794712
BEGIN 和 END 模块
通常,对于每个输⼊⾏, awk 都会执⾏每个脚本代码块⼀次。然⽽,在许多编程情况中,可能需要在 awk 开始处理输⼊⽂件中的⽂本之前执⾏初始化代码。对于这种情况, awk 允许您定义⼀个 BEGIN 块。
因为 awk 在开始处理输⼊⽂件之前会执⾏ BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引⽤的全局变量的极佳位置。
awk 还提供了另⼀个特殊块,叫作 END 块。 awk 在处理了输⼊⽂件中的所有⾏之后执⾏这个块。通常, END 块⽤于执⾏最终计算或打印应该出现在输出流结尾的摘要信息。
实例⼀:统计/etc/passwd的账户⼈数
[root@Gin scripts]# awk '{count++;print $0;} END{print "user count is ",count}' passwd
root:x:0:0:root:/root:/bin/bash ..............................................
user count is  27
count是⾃定义变量。之前的action{}⾥都是只有⼀个print,其实print只是⼀个语句,⽽action{}可以有多个语句,以;号隔开。这⾥没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:
[root@Gin scripts]# awk 'BEGIN {count=0;print "[start] user count is ",count} {count=count+1;print $0} END{print "[end] user count is ",count}' passwd [start] user count is  0
root:x:0:0:root:/root:/bin/bash ...................................................................
[end] user count is  27
实例⼆:统计某个⽂件夹下的⽂件占⽤的字节数
[root@Gin scripts]# ll |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ",size}'
[end]size is  1489
如果以M为单位显⽰:
[root@Gin scripts]# ll |awk 'BEGIN{size=0;} {size=size+$5;} END{print "[end]size is ",size/1024/1024,"M"}'
[end]size is  0.00142002 M
awk运算符
awk 赋值运算符:a+5;等价于: a=a+5;其他同类
[root@Gin scripts]# awk 'BEGIN{a=5;a+=5;print a}'
10
awk逻辑运算符:
[root@Gin scripts]# awk 'BEGIN{a=1;b=2;print (a>2&&b>1,a=1||b>1)}'
0 1
判断表达式 a>2&&b>1为真还是为假,后⾯的表达式同理
awk正则运算符:
[root@Gin scripts]# awk 'BEGIN{a="100testaa";if(a~/100/) {print "ok"}}'
ok
[root@Gin scripts]# echo|awk 'BEGIN{a="100testaaa"}a~/test/{print "ok"}'
ok
关系运算符:
如: > < 可以作为字符串⽐较,也可以⽤作数值⽐较,关键看操作数如果是字符串就会转换为字符串⽐较。两个都为数字才转为数值⽐较。字符串⽐较:按照ascii码顺序⽐较。
[root@Gin scripts]# awk 'BEGIN{a="11";if(a>=9){print "ok"}}' #⽆输出
[root@Gin scripts]# awk 'BEGIN{a=11;if(a>=9){print "ok"}}'
ok
[root@Gin scripts]# awk 'BEGIN{a;if(a>=b){print "ok"}}'
ok
awk 算术运算符:
说明,所有⽤作算术运算符进⾏操作,操作数⾃动转为数值,所有⾮数值都变为0。
[root@Gin scripts]# awk 'BEGIN{a="b";print a++,++a}'
0 2
[root@Gin scripts]# awk 'BEGIN{a="20b4";print a++,++a}'
20 22
这⾥的a++ , ++a与javascript语⾔⼀样:a++是先赋值加++;++a是先++再赋值
三⽬运算符 ?:
[root@Gin scripts]# awk 'BEGIN{a="b";print a=="b"?"ok":"err"}'
ok
[root@Gin scripts]# awk 'BEGIN{a="b";print a=="c"?"ok":"err"}'
err
常⽤ awk 内置变量
正则匹配指定字符串以后的内容注:内置变量很多,参阅相关资料
字段分隔符 FS
FS="\t" ⼀个或多个 Tab 分隔
[root@Gin scripts]#
ww  CC        IDD
[root@Gin scripts]# awk 'BEGIN{FS="\t+"}{print $1,$2,$3}'
ww  CC        IDD
FS="[[:space:]+]" ⼀个或多个空⽩空格,默认的
[root@Gin scripts]#
we are    studing awk now!
[root@Gin scripts]# awk -F [[:space:]+] '{print $1,$2,$3,$4,$5}'
we are
[root@Gin scripts]# awk -F [[:space:]+] '{print $1,$2}'
we are
FS="[" ":]+" 以⼀个或多个空格或:分隔
[root@Gin scripts]#
root:x:0:0:root:/root:/bin/bash
[root@Gin scripts]# awk -F [" ":]+ '{print $1,$2,$3}'
root x 0
字段数量 NF
[root@Gin scripts]#
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin:888
[root@Gin scripts]# awk -F ":" 'NF==8{print $0}'
bin:x:1:1:bin:/bin:/sbin/nologin:888
记录数量 NR
[root@Gin scripts]# ifconfig eth0|awk -F [" ":]+ 'NR==2{print $4}'  ## NR==2也就是取第2⾏
192.168.17.129
RS 记录分隔符变量
将 FS 设置成"\n"告诉 awk 每个字段都占据⼀⾏。通过将 RS 设置成"",还会告诉 awk每个地址记录都由空⽩⾏分隔。[root@Gin scripts]#
Jimmy the Weasel
100 Pleasant Drive
San Francisco,CA 123456
Big Tony
200 Incognito Ave.
Suburbia,WA 64890
[root@Gin scripts]#
#!/bin/awk
BEGIN {
FS="\n"
RS=""
}
{
print $1","$2","$3
}
[root@Gin scripts]# awk -
Jimmy the Weasel,100 Pleasant Drive,San Francisco,CA 123456
Big Tony,200 Incognito Ave.,Suburbia,WA 64890
OFS 输出字段分隔符
[root@Gin scripts]#
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin:888
[root@Gin scripts]# awk 'BEGIN{FS=":"}{print $1","$2","$3}' root,x,0
bin,x,1
[root@Gin scripts]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2,$3}' root#x#0
bin#x#1
ORS 输出记录分隔符
[root@Gin scripts]#
Jimmy the Weasel
100 Pleasant Drive
San Francisco,CA 123456
Big Tony
200 Incognito Ave.
Suburbia,WA 64890
[root@Gin scripts]#
#!/bin/awk
BEGIN {
FS="\n"
RS=""
ORS="\n\n"
}
{
print $1","$2","$3
}
[root@Gin scripts]# awk -
Jimmy the Weasel,100 Pleasant Drive,San Francisco,CA 123456
Big Tony,200 Incognito Ave.,Suburbia,WA 64890
awk 正则

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。