awk

awk的基本用法

awk [options]  'program'  var=value   file… 
awk [options]  -f programfile    var=value  file… 
awk [options]  'BEGIN{action;… }pattern{action;… }END{action;… }'  file ...

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。 

#sed 和grep 逐行处理

#逐行打印
[root04:33 AMcentos8 ~]#awk '{print "hello,awk"}'
ssss
hello,awk
                # 等待你标准输入,你输入一行他就处理一行
hello,awk
ss
hello,awk

[root04:35 AMcentos8 ~]#seq 5 | awk '{print "hello,awk"}'
hello,awk
hello,awk
hello,awk
hello,awk
hello,awk

#数值运算不要加双引号
[root04:36 AMcentos8 ~]#seq 3 | awk '{print 2*3}'
6
6
6

[root04:37 AMcentos8 ~]#awk -F: '{print "wang"}' /etc/issue
wang
wang
wang     #文件多少行,就打多少个wang 

[root04:37 AMcentos8 ~]#awk -F: '{print}' /etc/issue
\S
Kernel \r on an \m

[root04:40 AMcentos8 ~]#awk -F: '{print $1"\t"$3}' /etc/passwd

内置变量

-F 等价于 FS=
默认以空格作为分隔符
-F 以什么作为分隔符 等价于  -v  FS=
[root04:50 AMcentos8 ~]#awk -v FS=":" '{print $1FS$3 }' /etc/passwd |head -3
root:0
bin:1
daemon:2
[root04:50 AMcentos8 ~]#awk -v FS=":" '{print $1":"$3 }' /etc/passwd |head -3
root:0
bin:1                  用FS代替 ":"
daemon:2

引用shell中的变量
[root04:55 AMcentos8 ~]#S=:;awk -v FS=$S '{print $1FS$3}' /etc/passwd |head  -3
root:0
bin:1
daemon:2

OFS输出分隔符
[root04:59 AMcentos8 ~]#awk -v FS=":"  -v OFS="======"   '{print $1,$3 }' /etc/passwd |head -3
root======0                                    #默认是空格作为分隔符,加了OFS修改默认的分隔符
bin======1
daemon======2
或者
[root05:00 AMcentos8 ~]#S=:;awk -v FS=$S '{print $1"======="$3}' /etc/passwd |head  -3
root=======0
bin=======1
daemon=======2

RS 记录的分隔符
[root05:02 AMcentos8 /]#cat test 
a,b,c;12,
34,56,78;AA,
BB
#默认换行是行的分隔符,RS可以指定别的符号是分隔符
[root05:02 AMcentos8 /]#awk -F"," -v RS=";" '{print $1,$3}' test
a c                                #指定了;是每一条记录的分隔符
12 56
AA 

ORS 定义记录和记录之间的输出分隔符,默认是换行
[root05:12 AMcentos8 /]#awk -F"," -v RS=";"  -v ORS="+++" '{print $1,$3}' test
a c+++12 56+++AA +++[root05:13 AMcentos8 /]#

NF每一记录总共的字段数
[root05:16 AMcentos8 /]#cat test 
a,b,c;12,
34,56,78;AA,
BB
[root05:16 AMcentos8 /]#awk -F"," -v RS=";" '{print NF}' test
3
4
2
===========================================================
$NF  每一条记录的最后一列
[root05:18 AMcentos8 /]#awk -F: '{print $NF}' /etc/passwd |head -3
/bin/bash
/sbin/nologin
/sbin/nologin

$(NF-1) 倒数第二列

NR 打印每一条记录的编号
[root05:23 AMcentos8 /]#awk -F:   '{print NR,$0 }' /etc/passwd |head -3
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
#挑出指定的行来打
[root05:23 AMcentos8 /]#awk "NR==2" /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin

FNR 分开打印文件的行号
[root05:27 AMcentos8 /]#awk -F:   '{print FNR,$0 }' /etc/redhat-release  /etc/issue
1 CentOS Linux release 8.2.2004 (Core) 
1 \S
2 Kernel \r on an \m
3 

FILENAE
显示文件名
[root05:30 AMcentos8 /]#awk -F:   '{print FILENAME,FNR,$0 }' /etc/redhat-release  /etc/issue
/etc/redhat-release 1 CentOS Linux release 8.2.2004 (Core) 
/etc/issue 1 \S
/etc/issue 2 Kernel \r on an \m
/etc/issue 3 

ARGV   ARGC
[root05:32 AMcentos8 /]#awk -F:   '{print ARGC}' /etc/redhat-release  /etc/issue
3
3
3
3
[root05:32 AMcentos8 /]#awk -F:   '{print ARGV[0],ARGV[1],ARGV[2],ARGV[3]}' /etc/redhat-release  /etc/issue
awk /etc/redhat-release /etc/issue 
awk /etc/redhat-release /etc/issue     #  ARGV[3]为空值
awk /etc/redhat-release /etc/issue     三个参数
awk /etc/redhat-release /etc/issue 
 ARGC 命令行参数个数
 ARGV 数组,命令行所有给的的参数
[15:11:23root@localhost ~]#awk 'BEGIN{print ARGC}' /etc/fstab  /etc/issue
3
[15:12:19root@localhost ~]#awk 'BEGIN{print ARGV[1]}' /etc/fstab  /etc/issue
/etc/fstab
[15:12:43root@localhost ~]#awk 'BEGIN{print ARGV[0]}' /etc/fstab  /etc/issue
awk

自定义变量:

 -v  定义变量
变量名依然区分字符大小写,此时的/etc/fstab 文件是被拿来做遍历的
[15:13:48root@localhost ~]#awk -v test="hello gwak" '{print test}' /etc/fstab
hello gwak
hello gwak
hello gwak
hello gwak
hello gwak
hello gwak
hello gwak
hello gwak
hello gwak
hello gwak
hello gwak
[15:18:00root@localhost ~]#awk -v test="hello gwak" 'BEGIN{print test}' /etc/fstab
hello gwak
或者在program中直接定义:
[15:18:13root@localhost ~]#awk  'BEGIN{test="hello gwak";print test}' /etc/fstab
hello gwak

#变量是先赋值后使用
[root05:43 AMcentos8 /]#awk  -F: '{sex="male";print $1,sex,age;age=18}' /etc/passwd
root male 
bin male 18
daemon male 18
adm male 18
lp male 18
sync male 18

-f  选项
[root05:47 AMcentos8 /]#cat awktest 
{print script,$1,$2}
[root05:47 AMcentos8 /]#awk -F: -f awktest script="awk"  /etc/passwd |head -3
awk root x
awk bin x
awk daemon x

printf

%d %i 十进制有符号整数 
%u 十进制无符号整数 
%f 浮点数 
%s 字符串 
例如:
[16:04:24root@localhost ~]#awk -F: '{printf "%s",$1}' /etc/passwd
rootbindaemonadmlpsyncshutdownhaltmailoperatorgamesftpnobodyavahi-autoipdsystemd-bus-proxysystemd-networkdbuspolkitdtsspostfixsshdntprsyncrpcrpcusernfsnobodyapachemysqlwanghuauser3user4user5testuser7user8user9user6user1tomcentosgentookkkkerkker-zabbixsrvnginxsaslauth[16:11:08root@localhost ~]# 
[16:12:48root@localhost ~]#awk -F: '{printf "%s\n",$1}' /etc/passwd
  加 \n 自动换行
[16:14:43root@localhost ~]#awk -F: '{printf "USERNAME:%s\n",$1}' /etc/passwd
USERNAME:root
USERNAME:bin
USERNAME:daemon
USERNAME:adm
USERNAME:lp
USERNAME:sync
USERNAME:shutdown

[root05:51 AMcentos8 /]#awk -F: '{printf "USERNAME:%-20s UID:%d\n",$1,$3}' /etc/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

[root05:56 AMcentos8 /]#awk -F: 'BEGIN{print "----------------------"}{printf "USERNAME:%-10s| UID:%d\n---------------------\n",$1,$3}' /etc/passwd
----------------------
USERNAME:root      | UID:0
---------------------
USERNAME:bin       | UID:1
---------------------
USERNAME:daemon    | UID:2
---------------------
USERNAME:adm       | UID:3
---------------------

[root05:59 AMcentos8 /]#awk -F: 'BEGIN{print "----------------------"}{printf "USERNAME:%-10s| UID:%.2f\n---------------------\n",$1,$3}' /etc/passwd
----------------------
USERNAME:root      | UID:0.00
---------------------
USERNAME:bin       | UID:1.00
---------------------
USERNAME:daemon    | UID:2.00
---------------------

%c 字符的AIISC码 
%p 指针的值 
%e  %E科学计数法数值显示
%%  %自身
#[.#] 第一个数值控制显示的宽度 ,第二个#表示小数点后的精度
   %3.f
   例如:默认右对齐
[16:28:22root@localhost ~]#awk -F: '{printf "USERNAME:%s, UID:%d\n",$1,$3}' /etc/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
USERNAME:halt, UID:7

[16:25:07root@localhost ~]#awk -F: '{printf "USERNAME:%20s, UID:%d\n",$1,$3}' /etc/passwd
USERNAME:                root, UID:0
USERNAME:                 bin, UID:1
USERNAME:              daemon, UID:2
- 左对齐
[16:26:56root@localhost ~]#awk -F: '{printf "USERNAME:%-20s, UID:%d\n",$1,$3}' /etc/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
+ 显示数值符号

取非

[root06:25 AMcentos8 ~]#awk -v n=0 '!n++{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root06:25 AMcentos8 ~]#awk -v n=1 '!n++{print $0}' /etc/passwd
[root06:26 AMcentos8 ~]#awk -v n=-1 '!n++{print $0}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
[root06:26 AMcentos8 ~]#awk -v n=-1 '!++n{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash

打印第几行

[root06:27 AMcentos8 ~]#awk NR==2 /etc/issue
Kernel \r on an \m
[root06:29 AMcentos8 ~]#awk NR!=2 /etc/issue
\S

取奇偶

[root06:32 AMcentos8 ~]#seq 10 |awk NR%2!=0
1
3
5
7
9
[root06:32 AMcentos8 ~]#seq 10 |awk NR%2==0
2
4
6
8
10
[root06:32 AMcentos8 ~]#seq 10 |awk NR%2==1
1
3
5
7
9

[root07:31 AMcentos8 ~]#seq 10 |awk 'i=!i'
1
3        i的初始值为空   i取反得到1 第三次i=!i i的值为1  第四次判断i为真
5
7
9

[root07:32 AMcentos8 ~]#seq 10 |awk '!(i=!i)'
2
4
6
8
10

[root07:36 AMcentos8 ~]#seq 10 |awk  -v i=1  'i=!i'
2
4
6
8
10

[root07:37 AMcentos8 ~]#seq 10 |awk  -v i=0  'i=!i'
1
3
5
7
9

[root07:37 AMcentos8 ~]#seq 10 |awk '{i=!i;print i}'
1
0
1
0
1
0
1
0
1
0

正则表达式匹配

[root06:35 AMcentos8 ~]#awk -F: '$0 !~ /root/'  /etc/passwd |head -3
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
[root06:35 AMcentos8 ~]#awk -F: '$0 ~ /root/'  /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root06:35 AMcentos8 ~]#awk -F: '$0 ~ /root/{print $1}'  /etc/passwd
root
operator

[root06:48 AMcentos8 ~]#awk '/^UUID/' /etc/fstab 
UUID=55d00b68-d8ef-4c35-aa11-b8c11b91e867 /                       xfs     defaults        0 0
UUID=37e18d75-7231-4d84-8536-18e1b3a891f6 /boot                   ext4    defaults        1 2
UUID=fdcd162f-2ea2-4088-9e86-6a911336304a /data                   xfs     defaults        0 0
UUID=d81ef34a-c3dd-4483-b830-4cf516cbec7c swap                    swap    defaults        0 0
不写默认打印$0

!取反
[root06:49 AMcentos8 ~]#awk '!/^UUID/' /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Wed Apr 21 23:09:37 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#

条件表达式

[root06:42 AMcentos8 ~]#awk -F: '$3>=0 && $3<=1000 {print $1,$3}' /etc/passwd
[root07:06 AMcentos8 ~]#awk -F: '$NF~ /bash$/{print $1,$NF}' /etc/passwd
root /bin/bash
wang /bin/bash
li /bin/bash
zhang /bin/bash
[root07:06 AMcentos8 ~]#awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
root /bin/bash
wang /bin/bash
li /bin/bash
zhang /bin/bash

[root07:12 AMcentos8 ~]#awk -F: '$NF="/bin/AAAAA"{print $1,$NF}' /etc/passwd  |head -3
root /bin/AAAAA
bin /bin/AAAAA
daemon /bin/AAAAA

[root07:12 AMcentos8 ~]#seq 10 |awk 'NR>=3 && NR<=10'
3
4
5
6
7
8
9
10

[root07:15 AMcentos8 ~]#seq 10 |sed -n  3,10p
3
4
5
6
7
8
9
10

模式匹配

[root07:16 AMcentos8 ~]#awk '/^b/,/^f/' /etc/passwd      省略了print $0
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
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
上一篇:npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查


下一篇:RHCSA之账户与安全_账户与组的概念