文件处理三剑客之AWK


awk:Aho Weinberger Kernighan,报告生成器,格式化文本输出

基本语法

  awk [options] 'program' var=value file…
  awk [options] -f programfile var=value file…
  awk [options] 'BEGIN{action;… }pattern{action;… }END {action;… }' file ...
  awk 程序可由:BEGIN语句块、能够使用模式匹配的通用语句块、 END语句块,共3部分组成   program 通常是被放在单引号中

选项

  -F “分隔符” 指明输入时用到的字段分隔符
  -v var=value 变量赋值

基本格式

  awk [options] 'program' file…

Program

  pattern{action statements;..}

    pattern部分决定动作语句何时触发及触发事件
    BEGIN,END
    action statements对数据进行处理,放在{}内指明
    print, printf

分隔符、域和记录

  • awk执行时,由分隔符分隔的字段(域)标记$1,$2...$n称为域标识。 $0为所有域,注意:此时和shell中变量$符含义不同
  • 文件的每一行称为记录
  • 省略action,则默认执行 print $0 的操作

awk的工作原理

  1. 执行BEGIN{action;… }语句块中的语句
  2. 从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
  3. 当读至输入流末尾时,执行END{action;…}语句块
  4. BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
  5. END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块
  6. pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块

print格式

  print item1, item2, ...

print格式要点

  逗号分隔符
  输出item可以字符串,也可是数值;当前记录的字段、变量或awk的表达式
  如省略item,相当于print $0

变量

  内置变量和自定义变量

FS

输入字段分隔符,默认为空白字符

[root@centos ~]# awk -v FS=: '{print $1,FS,$3}' /etc/passwd  
root : 0  
bin : 1  
daemon : 2  
adm : 3  
lp : 4  
sync : 5  
shutdown : 6  
halt : 7  
....
相当于
[root@centos ~]# awk -F: '{print $1,$3}' /etc/passwd  
OFS

输出字段分隔符,默认为空白字符

[root@centos ~]# awk -v FS=: -v OFS='---------' '{print $1,$3}' /etc/passwd
root---------0
bin---------1
daemon---------2
adm---------3
lp---------4
sync---------5
shutdown---------6
halt---------7
....
RS

输入记录分隔符,指定输入时的换行符

[root@centos ~]# cat awk.txt
a,b,c;1,2,3;aa,dd,cc
zz,yy,ww;444,555,6663;AA
BB,CC
[root@centos ~]# awk -v FS="," -v RS=";" '{print $1}' awk.txt
a
1
aa
444
AA
BB
ORS

输出记录分隔符,输出时用指定符号代替换行符

[root@centos ~]# awk -v FS="," -v RS=";" -v ORS='-------' '{print $1}' awk.txt
a-------1-------aa-------444-------AA
BB-------
NF

字段数量

[root@centos ~]# awk -F: '{print NF}' awk.txt #awk引用变量时,变量前不需要加$
1
1
1
[root@centos ~]# awk -F, '{print NF}' awk.txt
7
5
2
[root@centos ~]# awk -F, '{print $(NF-1)}' awk.txt
dd
555
BB
NR

记录号

统计/etc/passwd文件里每行对应的用户名
[root@centos ~]# awk -F: -v OFS='----------' '{print NR,$1}' /etc/passwd
1----------root
2----------bin
3----------daemon
4----------adm
5----------lp
6----------sync
7----------shutdown
8----------halt
9----------mail
10----------operator
....
多个文件行数合并计数
[root@centos ~]# awk '{print NR}' /etc/fstab /etc/issue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FNR:各文件分别计数,记录号
多个文件单个计数
[root@centos ~]# awk '{print FNR}' /etc/fstab /etc/issue
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
FILENAME:当前文件名
[root@centos ~]# awk '{print FILENAME}' /etc/fstab /etc/issue
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/issue
/etc/issue
/etc/issue
/etc/issue
ARGC:命令行参数的个数
[root@centos ~]# awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue
3
ARGV:数组,保存的是命令行所给定的各参数
[root@centos ~]# awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/issue
awk
[root@centos ~]# awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/issue
/etc/fstab
[root@centos ~]# awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue
/etc/issue
自定义变量(区分字符大小写)
  1. -v var=value
  2. 在program中直接定义
[root@centos ~]# awk -F: '{title="CEO";print title":"$1}' /etc/passwd
CEO:root
CEO:bin
CEO:daemon
CEO:adm
CEO:lp
CEO:sync
CEO:shutdown
CEO:halt
....

printf命令的使用

格式化输出

 printf “FORMAT” , item1, item2, ...

  1. 必须制定FORMAT
  2. 不会自动换行,需要显式给出换行控制符,\n
  3. FORMAT中需要分别为后面每个item指定格式符

格式符:与item一一对应

  %c:显示字符的ASCII码
  %d, %i:显示十进制整数
  %e, %E:显示科学计数法数值
  %f:显示为浮点数
  %g, %G:以科学计数法或浮点形式显示数值
  %s:显示字符串
  %u:无符号整数
  %%:显示%自身

以分号为分隔符,取第一段字符
[root@centos ~]# awk -F: '{printf "%s\n",$1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
....
修饰符

  #[.#] 第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f
  - 左对齐(默认右对齐) %-15s
  + 显示数值的正负符号 %+d

取小数点后精度
[root@centos ~]# awk 'BEGIN{srand();printf "%.1f",rand()}'
0.5
[root@centos ~]# awk 'BEGIN{srand();printf "%.2f",rand()}'
0.05
[root@centos ~]# awk 'BEGIN{srand();printf "%.3f",rand()}'
0.799

添加注释,并控制其显示格式
[root@centos ~]# awk -F: 'BEGIN{print "Usernamem          UID"}{printf "%-15s %5d\n",$1,$3}' /etc/passwd | head
Usernamem          UID
root                0
bin                 1
daemon              2
adm                 3
lp                  4
sync                5
shutdown            6
halt                7
mail                8

操作符

算数操作符

  x+y, x-y, x*y, x/y, x^y, x%y
  - x:转换为负数
  +x:将字符串转换为数值

字符串操作符

  字符串连接,没有符号的操作符

赋值操作符

  =, +=, -=, *=, /=, %=, ^=,++, --

主要观察i++,++i的区别
[root@centos ~]# awk 'BEGIN{i=0;print i++,i}'
0 1
[root@centos ~]# awk 'BEGIN{i=0;print ++i,i}'
1 1
比较操作符

  ==, !=, >, >=, <, <=

以":"为分隔符,匹配第三段数值为0的行
[root@centos ~]# awk -F: '$3==0' /etc/passwd
root:x:0:0:root:/root:/bin/bash
模式匹配操作符

  ~:左边是否和右边匹配,包含
  !~:是否不匹配

$0代表了文件里的全部内容,在这里表示不匹配以"#"开头的行
[root@centos ~]# awk '$0 !~ /^#/' /etc/fstab

UUID=66002ce1-278d-4845-b822-79b86c947af8 /                       xfs     defaults        0 0
UUID=a2c11cbb-6d9d-4a63-b961-a4d57c4c85c9 /boot                   xfs     defaults        0 0
UUID=9043785a-2496-4966-8eb6-2959d7d943ce swap                    swap    defaults        0 0
/dev/sr0 /media/cdrom iso9660 defaults 0 0

这里表示匹配"#"开头的行
[root@centos ~]# awk '$0 ~ /^#/' /etc/fstab
#
# /etc/fstab
# Created by anaconda on Tue Mar  5 20:52:08 2019
#
# 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
#
逻辑操作符

  与&&,或||,非!

这里表示不匹配以"#"和空行的行
[root@centos ~]# awk '$0 !~ /^#/ && $0 !~ /^$/' /etc/fstab
UUID=66002ce1-278d-4845-b822-79b86c947af8 /                       xfs     defaults        0 0
UUID=a2c11cbb-6d9d-4a63-b961-a4d57c4c85c9 /boot                   xfs     defaults        0 0
UUID=9043785a-2496-4966-8eb6-2959d7d943ce swap                    swap    defaults        0 0
/dev/sr0 /media/cdrom iso9660 defaults 0 0

以":"为分隔符,取第三段为0或者>=1000的行
[root@centos ~]# awk -F: '$3==0 || $3>=1000' /etc/passwd
root:x:0:0:root:/root:/bin/bash
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
dxy:x:1000:1000:dxy:/home/dxy:/bin/bash

以":"为分隔符,取第三段非大于10的行
[root@centos ~]# awk -F: '!($3>=10)' /etc/passwd
root:x:0:0:root:/root:/bin/bash
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
条件表达式(三目表达式)

  selector?if-true-expression:if-false-expression

以":"作为分隔符,当第三段数值>=1000时输出"system user:用户名      uid值",否则输出"common user:用户名      uid值"
[root@centos ~]# awk -F: '$3>=1000?user="common user":user="system user"{printf "%s: %-20s %5d\n",user,$1,$3}' passwd.txt
system user: root                     0
common user: bin                   1000
system user: daemon                   2
common user: nfsnobody            65534
system user: adm                      3
common user: lp                    1040
system user: sync                     5
system user: shutdown                 6
system user: halt                     7
common user: dxy                   1000
system user: mail                     8
system user: operator                11

awk中的PATTERN

  根据pattern条件,过滤匹配的行,再做处理

  1. 如果未指定:空模式,匹配每一行
  2. /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
    awk '/^UUID/{print $1}' /etc/fstab
    awk '!/^UUID/{print $1}' /etc/fstab
  3. relational expression: 关系表达式,结果为“真”才会被处理
    真:结果为非0值,非空字符串
    假:结果为空字符串或0值
  4. line ranges:行范围
    startline,endline:/pat1/,/pat2/ 不支持直接给出数字格式
  5. BEGIN/END模式
    BEGIN{}:仅在开始处理文件中的文本之前执行一次
    END{}:仅在文本处理完成之后执行一次

再pattern中,如果未指定条件,即空模式,则匹配到每一行
[root@centos ~]# awk -F: 'i=1;j=1{print i,j}' passwd.txt
root:x:0:0:root:/root:/bin/bash
1 1
bin:x:1000:1000:bin:/bin:/sbin/nologin
1 1
daemon:x:2:2:daemon:/sbin:/sbin/nologin
1 1
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
1 1
adm:x:3:4:adm:/var/adm:/sbin/nologin
1 1
lp:x:1040:1070:lp:/var/spool/lpd:/sbin/nologin
1 1
sync:x:5:0:sync:/sbin:/bin/sync
1 1
....
匹配存在字符串"root"的行
[root@centos ~]# awk '/root/' passwd.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

匹配以字符串"root"开头的行
[root@centos ~]# awk '/^root/' passwd.txt
root:x:0:0:root:/root:/bin/bash

匹配最后一个字段为"/bin/bash"的行
[root@centos ~]# awk -F: '$NF=="/bin/bash"' passwd.txt
root:x:0:0:root:/root:/bin/bash
dxy:x:1000:1000:dxy:/home/dxy:/bin/bash

匹配最后一个字段以"/bash"结尾的行的第一个字段
[root@centos ~]# awk -F: '$NF ~ /bash$/{print $1}' passwd.txt
root
dxy

在关系表达式中,结果为"真"输出非空字符串,结果为"假"输出空字符串或0值
[root@centos ~]# awk '!0' passwd.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1000:1000:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/....
[root@centos ~]# awk '!1' passwd.txt

匹配以"root"的行和以"nobady"开头的行之间所有的内容
[root@centos ~]# awk -F: '/^root\>/,/^nobody\>/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
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
nobody:x:99:99:Nobody:/:/sbin/nologin

匹配第10行至第20行之间的行的第一个字段
[root@centos ~]# awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
10 operator
11 games
12 ftp
13 nobody
14 systemd-network
15 dbus
16 polkitd
17 libstoragemgmt
18 colord
19 rpc
20 gluster

BEGIN/END模式:BEGIN文本处理开始之前执行一次,END文本处理完成之后执行一次
[root@centos ~]# awk -F: 'BEGIN{print " USER UID \n--------------- "}{print $1,$3} END{print "=============="}' passwd.txt
 USER UID
---------------
root 0
bin 1000
daemon 2
nfsnobody 65534
adm 3
lp 1040
sync 5
shutdown 6
halt 7
dxy 1000
mail 8
operator 11
==============

awk控制语句:if-else

  语法
    if(condition){statement;…}[else statement]
    if(condition1){statement1}else if(condition2){statement2}else{statement3}
  使用场景
    对awk取得的整行或某个字段做条件判断

判断第三个字段是否>=1000,如果符合条件则print输出第一,三字段的内容
[root@centos ~]# awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd
nfsnobody 65534
dxy 1000

定义test变量,判断test值,>=90输出“very good”,90>=test>=60输出“good”,<=60时输出“no good”
[root@centos ~]# awk 'BEGIN{test=80;if(test>=90)print "very good";else if(test>=60)print "good";else print "no good"}'
good
[root@centos ~]# awk 'BEGIN{test=90;if(test>=90)print "very good";else if(test>=60)print "good";else print "no good"}'
very good
[root@centos ~]# awk 'BEGIN{test=50;if(test>=90)print "very good";else if(test>=60)print "good";else print "no good"}'
no good

awk控制语句:while循环

  语法
    while(condition){statement;…}
    条件“真”,进入循环;条件“假”,退出循环
  使用场景
    对一行内的多个字段逐一类似处理时使用
    对数组中的各元素逐一处理时使用

输出符合条件的行
[root@centos ~]# awk '/^[[:space:]]*linux16/' /boot/grub2/grub.cfg
	linux16 /vmlinuz-3.10.0-957.el7.x86_64 root=UUID=66002ce1-278d-4845-b822-79b86c947af8 ro rhgb quiet

默认以空格作为分隔符,输出字段,以及字段的长度
[root@centos ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg
linux16 7
/vmlinuz-3.10.0-957.el7.x86_64 30
root=UUID=66002ce1-278d-4845-b822-79b86c947af8 46
ro 2
rhgb 4
quiet 5

awk控制语句:do-while循环

  语法
    do {statement;…}while(condition)
  意义
    无论真假,至少执行一次循环体

[root@centos ~]# awk 'BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}'
5050

awk控制语句:for循环

  语法
    for(expr1;expr2;expr3) {statement;…}
  特殊用法:能够遍历数组中的元素
    语法:for(var in array) {for-body}

默认以空格作为分隔符,输出字段,以及字段的长度
[root@centos ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /boot/grub2/grub.cfg
linux16 7
/vmlinuz-3.10.0-957.el7.x86_64 30
root=UUID=66002ce1-278d-4845-b822-79b86c947af8 46
ro 2
rhgb 4
quiet 5

awk控制语句:switch语句

  语法
    switch(expression) {case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2; ...; default: statementn}

语句里的break、continue和next

[root@centos ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i} print sum}'
5050
break:符合条件直接跳出循环
[root@centos ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++) {if(i%2==0)break;sum+=i}print sum}'
1
continue:符合条件跳过本次循环,继续执行下次循环
[root@centos ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++) {if(i%2==0)continue;sum+=i}print sum}'
2500
next:符合条件则提前结束对本行处理而直接进入下一行处理
[root@centos ~]# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
root 0
daemon 2
lp 4
shutdown 6
mail 8
games 12
ftp 14
systemd-network 192
libstoragemgmt 998
rpc 32
gluster 996
....

awk数组

关联数组:array[index-expression]

  index-expression:
    1. 可使用任意字符串;字符串要使用双引号括起来
    2. 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”     3. 若要判断数组中是否存在某元素,要使用“index in array” 格式进行遍历

[root@centos ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}'
Monday
在awk中,若要遍历数组中的每个元素,要使用for循环

  语法:
    for(var in array) {for-body}
    var会遍历array的每个索引

[root@centos ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays){print weekdays[i]}}'
Tuesday
Monday

awk函数

函数处理

  rand():返回0和1之间一个随机数

[root@centos ~]# awk 'BEGIN{for(i=1;i<=10;i++)print rand()}'
0.237788
0.291066
0.845814
0.152208
0.585537
0.193475
0.810623
0.173531
0.484983
0.151863
字符串处理

  length([s]):返回指定字符串的长度

[root@centos ~]# echo ${a[@]}
Mon Tur Week
[root@centos ~]# echo ${a[@]} | awk '{print length($0)}'
12
[root@centos ~]# echo ${a[@]} | awk '{print length($1)}'
3
[root@centos ~]# echo ${a[@]} | awk '{print length($2)}'
3
[root@centos ~]# echo ${a[@]} | awk '{print length($3)}'
4

  sub(r,s,[t]):对t字符串搜索r表示模式匹配的内容,并将第一个匹配内容替换为s

[root@centos ~]# echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
2008-08:08 08:08:08

  gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容

[root@centos ~]# echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
2008-08-08 08-08-08

  split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,…

[root@centos ~]# awk 'BEGIN{time="2008:08:08 08:08:08";split(time,array,":");for(i in array){print i,array[i];}}'
4 08
5 08
1 2008
2 08
3 08 08

for…in 输出,因为数组是关联数组,默认是无序的。所以通过for…in 得到是无序的数组。如果需要得到有序数组,需要通过下标获得  

[root@centos ~]# awk 'BEGIN{time="2008:08:08 08:08:08";lens=split(time,array,":");for(i=1;i<=lens;i++){print i,array[i];}}'
1 2008
2 08
3 08 08
4 08
5 08

awk函数

自定义函数格式

  function name ( parameter, parameter, ... ) {

     statements
    return expression
   }

[root@centos ~]# chmod +x fun.awk #写完awk程序文件要加上执行权限
[root@centos ~]# cat fun.awk
function max(x,y){
	x>y?var=x:var=y
	return var
}
BEGIN{a=3;b=6;print max(a,b)}
[root@centos ~]# awk -f fun.awk #awk -f 引用awk函数程序文件
6
向awk脚本传递参数

  格式:
    awkfile var=value var2=value2... Inputfile
  在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通过-v 参数,让awk在执行BEGIN之前得到变量的值。命令行中每一个指定的变量都需要一个-v参数

[root@centos ~]# cat fun.awk
#!/bin/awk -f
function max(x,y){
	x>y?var=x:var=y
	return var
}
BEGIN{print max(a,b)}
[root@centos ~]# awk -v a=10 -v b=20 -f fun.awk
20
[root@centos ~]# awk -v a=100 -v b=20 -f fun.awk
100

awk中调用shell命令

system命令

  空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用""引用起来

awk调用shell命令
[root@centos ~]# awk 'BEGIN{system("hostname")}'
centos.magedu36.com
[root@centos ~]# awk 'BEGIN{system("ls")}'
a    anaconda-ks.cfg  awk.txt  Documents  fun.awk		Music	    Pictures  Templates  Videos
aaa  a.sh	      Desktop  Downloads  initial-setup-ks.cfg	passwd.txt  Public    test.txt

awk调用变量
[root@centos ~]# awk 'BEGIN{name="Darius";system("echo My name is " name)}'
My name is Darius
[root@centos ~]# awk 'BEGIN{score=100;system("echo Your score is  " score)}'
Your score is 100

AWK练习


解决DOS***生产案例:根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP,监控频率每隔5分钟。防火墙命令为:iptables -A INPUT -s IP -j REJECT
vim deny_dos.sh
while true ;do
    awk '/^[0-9]/{IP[$1]++}END{for(i in IP){if (IP[i]>=100)print i}}' /var/log/httpd/access_log | while read line;do iptables -A INPUT -s $line -j
    REJECT;done
    sleep 300
done
⽂件ip_list.txt如下格式,请提取“.magedu.com"前⾯的主机名部分并写⼊到该⽂件中

  1 blog.magedu.com
  2 www.magedu.com
  …
  999 study.magedu.com

awk -F'[" ".]' '{print $2}' ip_list.txt >> ip_list.txt
统计/etc/fstab⽂件中每个⽂件系统类型出现的次数
[root@centos ~]# awk '/^[UUID\/]/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' /etc/fstab
swap 1
xfs 2
iso9660 1