awk使用详解

一、awk基本用法

awk [options] 'scripts' file1,file2... 

awk [options] 'pattern {action}' file1,file2...

# -F选项指定分隔符,$num,代表第num个字段
[root@docker1 ~]# awk -F: '{print $1,$3}' /tmp/passwd 
root 0
bin 1
daemon 2
adm 3
......
#匹配正则表达式用:/正则表达式/,匹配以r开头的行
[root@ju ~]# awk -F: '/^r/{print $1}' /tmp/passwd
root
rtkit
#匹配第三列大于400的
[root@ju ~]# awk -F: '$3>=400{print $1,$3}' /tmp/passwd
rtkit 499
saslauth 498
pulse 497
jenkins 496
#匹配第三列大于497的,支持加法
[root@ju ~]# awk -F: '$3>=400+97{print $1,$3}' /tmp/passwd
rtkit 499
saslauth 498
pulse 497
#第七列以bash结尾的行
[root@ju ~]# awk -F: '$7~"bash$"{print $1,$3,$7}' /tmp/passwd
root 0 /bin/bash
#第七列不以bash结尾的行
[root@ju ~]# awk -F: '$7!~"bash$"{print $1,$3,$7}' /tmp/passwd
bin 1 /sbin/nologin
daemon 2 /sbin/nologin
adm 3 /sbin/nologin
lp 4 /sbin/nologin
......



二、awk内置变量

ARGC               命令行参数个数

ARGV               命令行参数排列

ENVIRON            支持队列中系统环境变量的使用

FILENAME           awk处理的文件名称

FS                 设置输入域分隔符,等价于命令行 -F选项

NF                 浏览记录的域的个数

NR                 awk命令已处理的行记录数;如果有多个文件,它会把处理的多个文件中行统一计数

FNR                与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数

OFS                输出字段分隔符

ORS                输出行分隔符

RS                 输入文本信息所使用的换行符

[root@docker1 ~]# awk -F: 'BEGIN{OFS="-----";}/^s/{print $1,$3}' /tmp/passwd
sync-----5
shutdown-----6
saslauth-----498
sshd-----74
[root@docker1 ~]# awk 'BEGIN{FS=":";OFS="-----"}/^s/{print $1,$3}' /tmp/passwd
sync-----5
shutdown-----6
saslauth-----498
sshd-----74


三、printf的格式用法

format格式的指示符都以%开头,后跟一个字符;如下:

%c: 显示字符的ASCII码

%d, %i:十进制整数

%e, %E:科学计数法显示数值

%f: 显示浮点数

%g, %G: 以科学计数法的格式或浮点数的格式显示数值

%s: 显示字符串

%u: 无符号整数

%%: 显示%自身


修饰符:

N: 显示宽度;

-: 左对齐;

+:显示数值符号;

[root@docker1 ~]# awk -F: '/^s/{printf "%-12s -----  %s\n",$1,$3}' /tmp/passwd
sync         -----  5
shutdown     -----  6
saslauth     -----  498
sshd         -----  74


四、输出重定向

print sth > outfile

print sth >> outfile

print sth | cmd


特殊文件描述符:

/dev/stdin:标准输入

/dev/sdtout: 标准输出

/dev/stderr: 错误输出

/dev/fd/N: 某特定文件描述符,如/dev/stdin相当于/dev/fd/0

[root@docker1 ~]# awk -F: '/^r/{printf "%-13s bash is %s\n",$1,$7 > "/tmp/test" }' /tmp/passwd
[root@docker1 ~]# cat /tmp/test 
root          bash is /bin/bash
rtkit         bash is /sbin/nologin


五、BEGIN和END的使用

[root@ju ~]# awk -F: 'BEGIN{print "--------begin---------"}{printf "%-20s%-10s\n",$1,$3}END{print "-------over--------"}' /tmp/passwd
--------begin---------
root                0         
bin                 1         
daemon              2         
adm                 3         
lp                  4                
......
sshd                74        
tcpdump             72        
jenkins             496       
-------over--------


六、控制语句

1、if-else语句

[root@docker1 ~]# awk -F: '{if ($7=="/sbin/nologin") printf "%-20s is %s\n", $1,"Nologin User"; else printf "%-20s is  %s\n", $1, "Login User"}' /etc/passwd
root                 is  Login User
bin                  is Nologin User
daemon               is Nologin User
adm                  is Nologin User
lp                   is Nologin User
sync                 is  Login User
shutdown             is  Login User
halt                 is  Login User
mail                 is Nologin User
......


2、while语句

[root@docker1 ~]# awk -F: '{i=1;while(i<=NF){if (length($i)>=20) {print $i "  is too long"};i++}}' /tmp/passwd
virtual console memory owner  is too long
/var/lib/avahi-autoipd  is too long
PulseAudio System Daemon  is too long
Privilege-separated SSH  is too long
Jenkins Continuous Integration Server  is too long

3、do-while语句

[root@docker1 ~]# awk -F: '{i=1;do {print i;i++}while(i<=1)}' /etc/passwd
1
1
1
1
1
1
......


4、for语句

[root@docker1 ~]# awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=20) {print $i "  is too long"}}}' /etc/passwd
virtual console memory owner  is too long
/var/lib/avahi-autoipd  is too long
PulseAudio System Daemon  is too long
Privilege-separated SSH  is too long
Jenkins Continuous Integration Server  is too long


5、break和continue

[root@docker1 ~]# awk -F: '{i=1;while(i<=NF){print $i;i++;break }}' /tmp/passwd
root
bin
daemon
adm
lp
sync
shutdown
......


6、next语句

[root@docker1 ~]# awk -F: '{if($1!="daemon") next;print $1}' /tmp/passwd 
daemon


七、awk中使用数组

[root@docker1 ~]# awk -F: '{UID[/^s/]++}END{for (i in UID){print i ,UID[i]}}' /tmp/passwd#以s开头的有4行,非s开头的有27行
0 27
1 4
[root@docker1 ~]# netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
ESTABLISHED 1
LISTEN 10


八、awk的内置函数


split(string, array [, fieldsep [, seps ] ])

功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从0开始的序列;


length([string])

功能:返回string字符串中字符的个数;


substr(string, start [, length])

功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;


system(command)

功能:执行系统command并将结果返回至awk命令


systime()

功能:取系统当前时间



这里只讲到了awk的很小一部分功能,awk是一个非常强大的工具,以后有时间再慢慢研究吧,掌握以上这些已经足够日常绝大部分情况下的使用了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章