awk的基本结构
1
2
3
4
5
6
7
8
9
10
11
12
13
|
awk
'BEGIN{} pattern {} END {}'
#pattern {} 部分是针对每行进行循环处理的,有pattern表示对匹配到的行处理,没有pattern表示对所有行处理
<br>[root@test88 etc]
# echo -e "line1\nline2" | awk 'BEGIN {print "Start"} {print} END {print "End"}'
Start
line1
line2
End
[root@test88 etc]
# echo | awk '{var1="v1";var2="v2";var3="v3";print var1,var2,var3;}' // ,表示用空格分割
v1 v2 v3
[root@test88 etc]
# echo | awk '{var1="v1";var2="v2";var3="v3";print var1"-"var2"-"var3;}' // "" 用于拼接字符串
v1-v2-v3
|
awk内置变量
NR 当前行的记录数,即行号
NF 当前行的字段数目
FS 字段分隔符
$0 整行文本
$1 第一个字段
$2 第二个字段
1
2
3
4
|
<br>[root@test88 etc]
# echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7" | awk '{print "Line no:"NR",No of fields:"NF,"$0="$0,"$1="$1,"$2="$2,"$3="$3}'
Line no:1,No of fields:3 $0=line1 f2 f3 $1=line1 $2=f2 $3=f3
Line no:2,No of fields:3 $0=line2 f4 f5 $1=line2 $2=f4 $3=f5
Line no:3,No of fields:3 $0=line3 f6 f7 $1=line3 $2=f6 $3=f7
|
可以用$NF表示最后一个字段
1
2
3
4
|
[root@test88 etc]
# echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7" | awk '{print $NF}' // 可以用$NF表示最后一个字段
f3
f5
f7
|
可以用NR统计行数
1
|
[root@test88 etc]
# awk 'END{print NR}' file //统计行数
|
使用awk进行简单的累加
1
2
3
4
5
6
7
8
9
|
[root@test88 etc]
# seq 5 | awk 'BEGIN {sum=0;print "Summation:"}{print $1"+";sum+=$1}END{print "==";print sum}'
Summation:
1+
2+
3+
4+
5+
==
15
|
将外部变量传进awk
1
2
3
4
5
6
7
8
9
|
[root@test88 etc]
# VAR=100000
[root@test88 etc]
# echo | awk -v VARIABLE=$VAR '{print VARIABLE}' // 使用外部变量
100000
[root@test88 etc]
# var1="Variable1";var2="Variable2"
[root@test88 etc]
# echo | awk '{print v1,v2}' v1=$var1 v2=$var2
Variable1 Variable2
[root@test88 etc]
# awk '{print v1,v2}' v1=$var1 v2=$var2 filename<br>[root@test88 ~]# awk '{print v1,v2}' v1=$var1 v2=$var2 /etc/hosts<br>Variable1 Variable2<br>Variable1 Variable2<br>Variable1 Variable2<br>Variable1 Variable2
|
匹配指定行进行操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
[root@test88 ~]
# cat file.txt
1
2
3
4
5
linux
linux win
win
[root@test88 ~]
# awk 'NR < 5' file.txt
1
2
3
4
[root@test88 ~]
# awk 'NR==1,NR==4' file.txt
1
2
3
4
[root@test88 ~]
# awk '/linux/' file.txt
linux
linux win
[root@test88 ~]
# awk '!/linux/' file.txt
1
2
3
4
5
win
|
指定匹配分隔符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[root@test88 ~]
# awk -F : '{print $NF}' /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
[root@test88 ~]
# awk 'BEGIN{FS=":"}{print $NF}' /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
|
使用getline获得命令的输出
1
2
|
[root@test88 ~]
# echo | awk '{"grep root /etc/passwd"|getline cmdout;print cmdout}' // getline获得命令输出并赋给cmdout变量,默认读取第一行输出
root:x:0:0:root:
/root
:
/bin/bash
|
使用for循环
1
2
3
4
5
6
7
8
9
|
[root@test88 ~]
# awk -F: '/root/{for(i=0;i<10;i++) {print $i}}' /etc/passwd
root:x:0:0:root:
/root
:
/bin/bash
root
x
0
0
root
/root
/bin/bash
|
length(string)返回字符串长度
1
2
|
[root@test88 ~]
# echo "linux" | awk '{print length($0)}'
5
|
index(string,search_string)返回目标字符串的位置
1
2
|
[root@test88 ~]
# echo "linux" | awk '{print index($0,"i")}'
2
|
倒序打印
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
[root@test88 ~]
# seq 9 | awk '{lifo[NR]=$0}END{for(lino=NR;lino>0;lino--){print lifo[lino];}}' //把内容放入数组,结束后再倒着输出一遍
9
8
7
6
5
4
3
2
1
[root@test88 ~]
# seq 9 | tac
9
8
7
6
5
4
3
2
1
|
提取IP地址
1
2
3
4
5
6
7
8
9
10
11
|
[root@test88 ~]
# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:D2:82:D9
inet addr:10.0.0.88 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed2:82d9
/64
Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:20531 errors:0 dropped:0 overruns:0 frame:0
TX packets:12613 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:26297973 (25.0 MiB) TX bytes:768281 (750.2 KiB)
[root@test88 ~]
# ifconfig | awk -F "[ :]+" 'NR==2{print $4}'
10.0.0.88
|
awk脚本
关于awk脚本,我们需要注意两个关键词BEGIN和END。
- BEGIN{ 这里面放的是执行前的语句 }
- END {这里面放的是处理完所有的行后要执行的语句 }
- {这里面放的是处理每一行时要执行的语句}
假设有这么一个文件(学生成绩表):
1
2
3
4
5
6
|
$
cat
score.txt
Marry 2143 78 84 77
Jack 2321 66 78 45
Tom 2122 48 77 71
Mike 2537 87 97 95
Bob 2415 40 57 62
|
我们的awk脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
$
cat
cal
.
awk
#!/bin/awk -f
#运行前
BEGIN {
math = 0
english = 0
computer = 0
printf
"NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
printf
"---------------------------------------------\n"
}
#运行中
{
math+=$3
english+=$4
computer+=$5
printf
"%-6s %-6s %4d %8d %8d %8d\n"
, $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
printf
"---------------------------------------------\n"
printf
" TOTAL:%10d %8d %8d \n"
, math, english, computer
printf
"AVERAGE:%10.2f %8.2f %8.2f\n"
, math
/NR
, english
/NR
, computer
/NR
}
|
我们来看一下执行结果
1
2
3
4
5
6
7
8
9
10
11
|
$
awk
-f
cal
.
awk
score.txt
NAME NO. MATH ENGLISH COMPUTER TOTAL
---------------------------------------------
Marry 2143 78 84 77 239
Jack 2321 66 78 45 189
Tom 2122 48 77 71 196
Mike 2537 87 97 95 279
Bob 2415 40 57 62 159
---------------------------------------------
TOTAL: 319 393 350
AVERAGE: 63.80 78.60 70.00
|
计算文件大小
1
2
|
[root@C ~]
# ls -l *.txt | awk '{sum+=$5}END{print sum}'
420
|
筛选文本长度
1
2
3
4
|
#打印长度大于4的文本行
[root@C ~]
# awk 'length>4' test.txt
liyong
oldboy
|