awk基础详细介绍

awk是什么呢?在linux下,awk是一种数据处理工具,一个特别强大的工具,文本处理三剑客之一,这个东西从一个层次来说是一种语言,特点也很多,这个在这里就不一一介绍了,主要来介绍一下其用法。(如果想了解可以看这里
基本语法
awk ‘{处理动作}’文件
在这里可以指定输入输出字段的分隔符,而处理动作就是在经过选项的规则定义后,awk怎么处理它,大多是print,也就是输出到终端。具体的在下面举例说明。这里我把/etc/passwd下的东西拷到了/app下并删除一些内容来演示。

[root@localhost app]#  awk '{print}' passwd

这样输出什么呢,直接打印,什么都没指定,当然是原文本内容了。

[root@localhost app]#  awk -v FS=":" '{print $1}' passwd
root
bin
daemon
adm
lp
sync
shutdown

这样写的意思就是指定输入分隔符为:然后打印以冒号为分隔的第一列,也就是用户名。在awk中 1 , 2…表示分割后的第几列,$0表示所有,也就是一行,而-v FS就是接下来要说的一个内容
awk的内置变量
FS:输入字段分隔符

[root@localhost app]# awk -v FS=':' '{print $1,$3}' passwd 
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6

OFS:输出字段分隔符

[root@localhost app]# awk -v FS=':' -v OFS=':' '{print $1,$3}' passwd 
root:0
bin:1
daemon:2
adm:3
lp:4
sync:5
shutdown:6

RS:输入的记录分隔符(不再以行为一个处理的单位,而是以记录分隔符分隔出的每段为一个处理单位)

[root@localhost app]#  awk -v FS=":" -v RS="\n" '{print $1}' passwd 
root
bin
daemon
adm
lp
sync
shutdown

ORS:输出的记录分隔符

[root@localhost app]# awk -v FS=":" -v RS="\n" -v ORS="#" '{print $1}' passwd 
root#bin#daemon#adm#lp#sync#shutdown#

NF:字段的数量
这里的字段数量指的就是在不指定记录分隔符的情况下,以某个分隔符分割开的每行字段的数量

[root@localhost app]# awk -F":" '{print NF}' passwd 
7
7
7
7
7
7
7

NR:记录号(就是行号)

[root@localhost app]# awk '{print NR,$0}' passwd 
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

FNR:各文件分别计数,行号(这里就是两个文件分别记行号不再演示了,如果有想看效果的可以自己试试)
FILENAME:当前文件名
因为文件中有七行,所以打印了七次(一开始就说过,awk本身就是一个循环)

[root@localhost app]# awk '{print FILENAME}' passwd
passwd
passwd
passwd
passwd
passwd
passwd
passwd

ARGC:命令行参数的个数

[root@localhost app]# awk 'BEGIN{print ARGC}' passwd 
2

这里为什么是2呢,因为说的是命令行参数,命令行中除了单引号引起来的awk的执行动作,其他的都是参数,所以有两个

扫描二维码关注公众号,回复: 11437896 查看本文章

ARGV:数组,保存的是命令行所给定的各参数

[root@localhost app]# awk 'BEGIN {print ARGV[1]}'  passwd 
passwd

上面说的这些变量都是awk内置的变量,当然我们还可以自定义变量
可以在里面或者外面定义,这里的里面外面是指网卡的执行动作外还是内,例如

[root@localhost app]# awk -v var=value 'BEGIN{print var}'
value
[root@localhost app]# awk 'BEGIN{var="value";print var}'
value

在这礼物我老是用BEGIN,其实还有一个END
BEGIN{}: 仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次
因为在这里我并没有处理文本,所以我打一个BEGIN

上面说的这些好像并不能显示出awk的强大,下面这个功能相比于其他的文本处理工具就显得很强
格式化输出
首先要说一下格式符和修饰符
格式符
%c: 显示字符的ASCII码
%d, %i: 显示十进制整数
%e, %E:显示科学计数法数值
%f:显示为浮点数
%g, %G:以科学计数法或浮点形式显示数值
%s:显示字符串
%u:无符号整数 %%: 显示%自身
修饰符
#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f
-: 左对齐(默认右对齐) %-15s
+:显示数值的正负符号 %+d

这个怎么用呢,我们来举例说明(依然是刚才的那个文件)

[root@localhost app]# awk -F: '{printf "Username:%s UID:%s\n",$1,$3}' passwd 
Username:root UID:0
Username:bin UID:1
Username:daemon UID:2
Username:adm UID:3
Username:lp UID:4
Username:sync UID:5
Username:shutdown UID:6
[root@localhost app]# awk -F: '{printf "Username:%-15s UID:%s\n",$1,$3}' passwd 
Username:root            UID:0
Username:bin             UID:1
Username:daemon          UID:2
Username:adm             UID:3
Username:lp              UID:4
Username:sync            UID:5
Username:shutdown        UID:6

这样的一个例子相信大家对格式化输出就知道怎么用了吧,我输出的内容是按照我想要的格式输出的,并且能对齐。其他的不再一一举例(想看效果的自己来试试就知道了)

awk是能够算数的,这一点很强吧,不用bc就能实现算数了,在学到这里的时候,我感觉这跟C语言的格式差不多的,后面的函数跟C也是一样的,学过C的也应该很快就能接受
awk的算数
赋值操作符 =, +=, -=, *=, /=, %=, ^=,++, -
比较操作符 ==, !=, >, >=, <, <=
模式匹配符:~ 左边是否匹配包含右边 !~不匹配

[root@localhost app]# awk '/^UUID/{print $1}' /etc/fstab 
UUID=9de0a348-803f-402d-af1f-77d36040de6e
UUID=3cb1bc37-9db5-4f1e-8a8b-76325a75d82b
UUID=93ac7b43-b3a0-4dcd-9bd6-f95987697b95
[root@localhost ~]# seq 10 |awk '!(i=!i)'
2
4
6
8
10

awk条件控制语句
这个条件控制语句就是前面的那shell脚本中的调监控和值与君写进来了,只不过有点不一样
if(condition) {statements;…} else {statements;…}
while(conditon) {statments;…}
do {statements;…} while(condition)
for(expr1;expr2;expr3) {statements;…}
break
continue

next:提前结束对本行处理而直接进入下一行处理(awk自身循环)
这里都是一些概念性的东西,看完之后来个例子具体了解一下吧

[root@localhost ~]# echo {1..10} |awk '{n=1;while(n<=NF){if($n%2==0){print $n,"oushuo"}else {print $n,"jishu"};n++}}'
1 jishu
2 oushuo
3 jishu
4 oushuo
5 jishu
6 oushuo
7 jishu
8 oushuo
9 jishu
10 oushuo

awk数组

array[index-expression]

index-expression可使用任意字符串;字符串要用双引号括起来
如果数组元素事先不存在,在引用时,awk会自动创建此元素,并初始化为空串
若要遍历输出数组中每个元素,则for循环
for(var in array) {print array[var]}

[root@localhost app]# awk -F: '{line[$7]++}END{for(i in line){print i,line[i]}}' passwd 
/sbin/shutdown 1
/bin/bash 1
/sbin/nologin 4
/bin/sync 1

在awk中海油一些类似sed的用法,替换以及另外一点用法
数值及字符串处理
rand():返回0和1之间一个随机数
产生一个1~100的随机数

[root@localhost app]# awk 'BEGIN{srand();print int(rand()*100) }' 
73

length([s]):返回指定字符串的长度

[root@localhost app]# echo "hello world" |awk '{print length($1)}'
5

sub(r,s,[t]):对字符串t进行搜索,匹配到r的替换为s(只替换匹配到的第一个)

[root@localhost app]# echo "2018:8:30" |awk 'sub(/:/,"-",$0)'
2018-8:30

gsub(r,s[t]):同样是匹配替换,跟上面不同的是全局替换

[root@localhost app]# echo "2018:8:30" |awk 'gsub(/:/,"-",$0)'
2018-8-30

split(s,array,[r]):以r为分隔符切割字符串s,把切割的每个结果放进数组中并依次把索引值设为1,2…

[root@localhost app]# netstat -tan |awk '/^tcp\>/&& !($5 ~ "*") {split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'
172.18.254.125 2

awk函数
function name(parameter, parameter,…){
statements
return expression
}
awk -f name 一般awk函数写入文件中,用-f来指定动作,即函数

在awk中引用shell变量
system命令 如果system中需要使用awk中的变量可以使用空格分隔,或者说除了 awk的变量外其他一律用”“引用起来。即
awk BEGIN’{system(“hostname”)}’

[root@localhost app]# awk 'BEGIN{score=100;system("name=zhangsan;echo $name score is "score )}'
zhangsan score is 100

最后awk还可以写成脚本
vim f2.awk
#!/bin/awk -f
{if ( 3 >= 10 ) p r i n t 1,$3}
wq保存退出
./f2.awk -F: /etc/passwd

[root@localhost ~]# ./f2.awk -F: /etc/passwd
uucp 10
operator 11
games 12
gopher 13
ftp 14
nobody 99
dbus 81
usbmuxd 113
rtkit 499
avahi-autoipd 170

向脚本传递参数
vim test.awk
#!/bin/awk –f {if( 3 >=min && 3<=max)print 1 , 3}
chmod +x test.awk
test.awk -F: min=100 max=200 /etc/passwd
在这里只是大致列出了awk的基础,我这里下载了一个awk的电子版,这是翻译过来的,看着不是很舒服,但是还是可以看的,如果你真的想学的话百度网盘 提取码2fid

猜你喜欢

转载自blog.csdn.net/professorman/article/details/82218369