打印hello world的几种方式
[root@localhost ~]# echo | awk '{print "hello world"}'
hello world
[root@localhost ~]# echo -e " \n \n" | awk '{print "hello world"}'
hello world
hello world
hello world
[root@localhost ~]# cat a
hello ,world
[root@localhost ~]# awk '{print}' a
hello ,world
打印文件的第一列
[root@c2 ~]# awk -F: '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
没有对像操作
awk中只能用双引号
结构: begin(不需要对象可以处理) 主体(写到主体必须要有对象) end(归纳)
[root@localhost ~]# awk 'BEGIN{print "hello world"}'
hello world
[root@localhost ~]# cat kk
hello,world
hello
hi
[root@localhost ~]# vi kk
[root@localhost ~]# awk '/^$/{print "This is ablank line."}' kk
This is ablank line.
This is ablank line.
This is ablank line.
This is ablank line.
[root@c2 ~]# awk 'BEGIN{print}/^$/{print "This is ablank line."}' kk
This is ablank line.
This is ablank line.
This is ablank line.
This is ablank line.
awk 允许使用字段操作符$来指定字段
$1: 表示第一段
$2: 表示第二段
$0: 表示整个字段
[root@localhost ~]# awk '{print $1,$2,$3}' ll
jerry thistest 888-999-000
[root@localhost ~]# awk '{print $1$2$3}' ll
jerrythistest888-999-000
[root@localhost ~]# awk '{print $1":"$2":"$3}' ll
jerry:thistest:888-999-000
[root@localhost ~]# awk '{print $0}' ll
jerry thistest 888-999-000
一行中调换位置顺序
[root@localhost ~]# cat ll
jerry thistest 888-999-000
[root@localhost ~]# awk '{print $3,$1,$2}' ll
888-999-000 jerry thistest
用awk计算数字
加 、减 、 乘 、除 、取余
[root@localhost ~]# echo a b c d | awk 'BEGIN{one=1;two=2}{print $(one+two)}'
c
[root@localhost ~]# awk 'BEGIN{print 1+2}'
3
[root@localhost ~]# awk 'BEGIN{print 4/10}'
0.4
[root@localhost ~]# awk 'BEGIN{print 4*10}'
40
[root@localhost ~]# awk 'BEGIN{print 2**2}'
4
[root@localhost ~]# awk 'BEGIN{print 10%2}'
0
-F: 改变字段的分隔符,而不只是用数字和变量
\t: 表示一个实际的制表符的转义序列
[root@localhost ~]# awk -F'\t' '{print $1}' ll
jerry thistest
[root@c2 ~]# awk -F'\t' '{print $1}' ll
jerry thistest 888-999-000
[root@localhost ~]# awk -F'\t\n' '{print $1}' ll
jerry thistest 888-999-000
FS: 可以通过FS来改变字段分隔符
[root@c2 ~]# awk -F'\t' '{print $2}' ll
888-999-000
[root@c2 ~]# awk 'BEGIN{FS="\t"}{print $2}' ll
888-999-000
不同表示之间的区别:
FS = “\t” : 将每个制表符作为一个字段分隔符
FS = “ \t++” : 表示用一个或多个制表符来分隔字段
FS = “ [ \t]” : 使用一个正则表达式指定几个字段为分隔符
取出ip地址: 两种方式
[root@c2 ~]# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:a4:aa:a2 brd ff:ff:ff:ff:ff:ff
altname enp3s0
inet 192.168.136.140/24 brd 192.168.136.255 scope global dynamic noprefixroute ens160
valid_lft 1281sec preferred_lft 1281sec
inet6 fe80::20c:29ff:fea4:aaa2/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@c2 ~]# ip a | grep 'inet ' | grep -v '127' | awk '{print $2}' | awk -F'/' '{print $1}'
192.168.136.140
[root@localhost ~]# ip a | grep 'inet ' | grep -v '127' | awk -F '[ /]+' '{print $3}'
192.168.136.136
[root@localhost ~]#
表达式:
序列 | 描述 |
---|---|
\a | 报警字符,通常时ASC|| BEL 字符 |
\b | 退格键 |
\f | 走字符 |
\n | 换行符 |
\r | 回车 |
\t | 水平分割线 |
\v | 垂直分割线 |
\ddd | 将字符表示为1到3为八进制 |
\xbex | 将字符表示为十六进制值 |
\c | 任何需要字面表示的字符c |
变量是引用值的标识符
定义变量(只能由数字、字母、下划线,但不能以数字开头)
[root@localhost ~]# awk 'BEGIN{a= "hello" "world"} {print a}' a
helloworld
[root@localhost ~]# awk 'BEGIN{a= "hello"" ""world"} {print a}' a
hello world
[root@localhost ~]# awk 'BEGIN{a= "hello world"} {print a}' a
hello world
算术操作符
操作符 | 描述 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取模 |
^ && ** | 取幂 |
[root@localhost ~]# awk 'BEGIN{print 2^4}'
16
[root@localhost ~]# awk 'BEGIN{print 2**4}'
16
[root@localhost ~]# awk 'BEGIN{x=1;y=x+1}{print y}' a
2
操作符 | 定义 |
---|---|
++ | 变量加1 |
– | 变量减1 |
+= | 将加的结果赋给变量 |
-= | 将减的的结果赋给变量 |
*= | 将乘的的结果赋给变量 |
/+ | 将除的的结果赋给变量 |
%= | 将取模的的结果赋给变量 |
^= 和 **= | 将取幂的的结果赋给变量 |
统计空行数
[root@localhost ~]# cat kk
hello,world
hello
hi
[root@localhost ~]# awk '/^$/{print x+=1}' kk (x 没有定义的时候默认为0)
1
2
3
4
区别:
++x(先加在打印)
x ++ (先打印再加)
[root@localhost ~]# awk '/^$/{print ++x}' kk
1
2
3
4
[root@localhost ~]# awk '/^$/{print x++}' kk
0
1
2
3
在主体里面运算完之后在结果里面打印
[root@localhost ~]# awk '/^$/{++x}END{print x}' kk
4
平均值
[root@localhost ~]# cat ss
jerry 90 89 80 87 88 67
sairr 90 80 90 90 90 90
gerrt 98 98 90 97 70 80
[root@localhost ~]# awk '{total=$2+$3+$4+$5+$6;avg=total/5;print $1, avg }' ss
jerry 86.8
sairr 88
gerrt 90.6
[root@localhost ~]# cat ss
jerry 90 89 80 87 88 67
sairr 90 80 90 90 90 90
gerrt 98 98 90 97 70 80
[root@localhost ~]# awk -F'90' '{print $1}' ss
jerry
sairr
gerrt 98 98
[root@localhost ~]# cat ss
jerry 90 89 80 87 88 67
sairr 90 80 90 90 90 90
gerrt 98 98 90 97 70 80
[root@localhost ~]# awk '{print $1}' ss
jerry
sairr
gerrt
[root@localhost ~]# awk -F'\t' '{print $1}' ss
jerry
sairr 90 80 90 90 90 90
gerrt 98 98 90 97 70 80
OFS: FS 等效的输出OFS,它的默认值为一个空格
[root@localhost ~]# cat ss
jerry 90 89 80 87 88 67
sairr 90 80 90 90 90 90
gerrt 98 98 90 97 70 80
[root@localhost ~]# awk 'BEGIN{FS= " "}{print $1,$3}' ss
jerry 89
sairr 80
gerrt 98
[root@localhost ~]# awk 'BEGIN{FS= " ";OFS=":"}{print $1,$3}' ss
jerry:89
sairr:80
gerrt:98
[root@localhost ~]# awk 'BEGIN{FS= " ";OFS=":"}{print $1 $3}' ss
jerry89
sairr80
gerrt98
[root@localhost ~]# head /etc/passwd | awk 'BEGIN{FS=":";OFS="-"}{print $1,$3}'
root-0
bin-1
daemon-2
adm-3
lp-4
sync-5
shutdown-6
halt-7
mail-8
operator-11
POSIX 增加了一个新的变量CONVFMT,它用来控制数字到字符串的转换
[root@localhost ~]# awk 'BEGIN{print 5.5+2.4 " is a test."}'
7.9 is a test.
NR : 行号
[root@c2 ~]# ip a | grep 'inet ' | awk -F'[ /]+' 'NR==2{print $3}'
192.168.136.140
NF: 列数
$NF: 打印最后一列
[root@localhost ~]# awk '{print NF}' ss
7
7
7
[root@localhost ~]# awk '{print $NF}' ss
67
90
80
打印倒数第一行
[root@localhost ~]# cat ss
jerry 90 89 80 87 88 67
sairr 90 80 90 90 90 90
gerrt 98 98 90 97 70 80
[root@localhost ~]# awk '{print $(NF-1)}' ss
88
90
70
[root@c2 ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 351M 0 351M 0% /dev
tmpfs tmpfs 370M 0 370M 0% /dev/shm
tmpfs tmpfs 370M 5.4M 365M 2% /run
tmpfs tmpfs 370M 0 370M 0% /sys/fs/cgroup
/dev/mapper/cs-root xfs 17G 6.9G 11G 41% /
/dev/sda1 xfs 1014M 226M 789M 23% /boot
tmpfs tmpfs 74M 0 74M 0% /run/user/0
[root@c2 ~]#
[root@c2 ~]# df -h | awk 'NR==1{print $(NF-1),$NF}NR!=1{print $NF}'
Mounted on
/dev
/dev/shm
/run
/sys/fs/cgroup
/
/boot
/run/user/0
处理多行记录
RS
ORS
[root@localhost ~]# awk 'BEGIN{FS="\n";RS=":"}{print $1,$NF}' ll
jerry thistest 888-999-000
[root@localhost ~]# awk 'BEGIN{FS="\n";RS="";OFS="\n";ORS="\n\n"}{print $1,$NF}' ll
jerry thistest 888-999-000
jerry thistest 888-999-000
[root@localhost ~]# awk 'BEGIN{FS="\n";RS=""}{print $1,$NF}' ll
jerry thistest 888-999-000 jerry thistest 888-999-000
支票簿结算
[root@localhost ~]# cat bb
1000
125 Marhet -125.45
126 Jerry -89.3
127 kkkkd -79.2
128 xxich -50.2
129 hshdv -88.9
[root@localhost ~]# awk 'NR==1{print "begin balance:\t" $1 }' bb
begin balance: 1000
[root@localhost ~]# awk 'NR==1{print "begin balance:\t" $1;balance=$1;next}{print $1,$2,$3}' bb
begin balance: 1000
125 Marhet -125.45
126 Jerry -89.3
127 kkkkd -79.2
128 xxich -50.2
129 hshdv -88.9
[root@localhost ~]#
[root@localhost ~]# awk 'NR==1{print "begin balance:\t" $1;balance=$1;next}{print $1,$2,$3;print balance+=$NF}' bb
begin balance: 1000
125 Marhet -125.45
874.55
126 Jerry -89.3
785.25
127 kkkkd -79.2
706.05
128 xxich -50.2
655.85
129 hshdv -88.9
566.95
关系操作符和布尔操作符
操作符 | 描述 |
---|---|
< | 小于 |
== | 相等的 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
!= | 不等的 |
~ | 匹配 |
!- | 不匹配 |
布尔操作符
操作符 | 定义 |
---|---|
|| | 逻辑或 |
&& | 逻辑与 |
! | 逻辑非 |
例:
NF == 6 && NR > 1
打印文件的大小和名字
[root@localhost ~]# ll | awk 'NR!=1{printf "%d\t%s",$5,$9}'
72 !13 a1336 anaconda-ks.cfg88 bb25 kk28 ll73 ss[root@localhost ~]# ll | awk 'NR!=1{printf "%d\t%s\n",$5,$9}'
72 !
13 a
1336 anaconda-ks.cfg
88 bb
25 kk
28 ll
73 ss
用filenume来累加列表中文件的数量
[root@c2 ~]# ll | awk '{sum+=$5;++filenum;print $5,"\t",$9}'
1246 anaconda-ks.cfg
70 b
125 bbb
104 c
93 cc
20 d
90 kk
28 ll
356 ttt
119 yy
[root@c2 ~]# ll | awk '{sum+=$5;++filenum;print $5,"\t",$9}END{print "Total: ",sum}'
1246 anaconda-ks.cfg
70 b
125 bbb
104 c
93 cc
20 d
90 kk
28 ll
356 ttt
119 yy
Total: 2251
[root@c2 ~]# ll | awk '{sum+=$5;++filenum;print $5,"\t",$9}END{print "Total: ",sum,"bytes"}'
1246 anaconda-ks.cfg
70 b
125 bbb
104 c
93 cc
20 d
90 kk
28 ll
356 ttt
119 yy
Total: 2251 bytes
[root@c2 ~]# ll | awk '{sum+=$5;++filenum;print $5,"\t",$9}END{print "Total: ",sum,"bytes("filenum" file)"}'
1246 anaconda-ks.cfg
70 b
125 bbb
104 c
93 cc
20 d
90 kk
28 ll
356 ttt
119 yy
Total: 2251 bytes(11 file)
[root@c2 ~]# ll | awk 'NR!=1{sum+=$5;++filenum;print $5,"\t",$9}END{print "Total: ",sum,"bytes("filenum" file)"}'
1246 anaconda-ks.cfg
70 b
125 bbb
104 c
93 cc
20 d
90 kk
28 ll
356 ttt
119 yy
Total: 2251 bytes(10 file)
格式化打印
printf 的格式说明符
字符 | 定义 |
---|---|
c | ASCLL 字符 |
d | 十进制整数 |
i | 十进制整数(在POSIX中增加的) |
e | 浮点格式 |
E | 浮点格式 |
f | 浮点格式 |
g | e或f 的转格式,长度最短,末尾的0被去掉 |
G | E或F 的转格式,长度最短,末尾的0被去掉 |
O | 无符号的八进制 |
s | 字符串 |
u | 无符号的十六进制 |
x | 无符号的十六进制,用a-f表示10-15 |
X | 无符号的十六进制,用A-F表示10-15 |
% | 字面字符% |
printf (不换行)
可以格式化输出
[root@localhost ~]# awk 'BEGIN{printf "|%10s|","hello"}'
| hello|[root@localhost ~]#
用printf 产生一个输出,他输出不同的两个字段上的字符串和十进制
[root@localhost ~]# awk 'BEGIN{printf "|%-10s|","hello"}'
|hello |[root@localhost ~]#
[root@localhost ~]# awk 'BEGIN{printf "|%-10d|","100"}'
|100 |[root@localhost ~]#
与END 在一起的用法
[root@c2 ~]# ll | awk 'BEGIN{print "bytes","\t","file"}NR!=1{sum+=$5;++filenum;print $5,"\t",$9}END{printf "Total: \t%d bytes(%d file)",sum,filenum}'
bytes file
1246 anaconda-ks.cfg
70 b
125 bbb
104 c
93 cc
20 d
90 kk
28 ll
356 ttt
119 yy
Total: 2251 bytes(10 file)[root@c2 ~]#
while循环
[root@localhost ~]# awk 'BEGIN{do{++i;print i}while (i<=4)}'
1
2
3
4
5
[root@localhost ~]# awk 'BEGIN{do{++i;print i}while (i<4)}'
1
2
3
4
[root@localhost ~]# awk 'BEGIN{while(i<=4){print i;i++}}'
1
2
3
4
[root@localhost ~]# awk 'BEGIN{while(i<4){++i;print i}}'
1
2
3
4
[root@localhost ~]# awk 'BEGIN{while(i<=4){++i;print i}}'
1
2
3
4
5