awk常见操作

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

猜你喜欢

转载自blog.csdn.net/xiaoyangsavvy/article/details/80074257