awk文本处理

  独立的编程语言,有流程控制,可以顶一变量,有自己的函数。

  通常和shell连用,获取指定的数据给shell脚本处理。

  单独使用时,主要用来对数据统计。

awk语法格式

  -awk [选项] ‘[条件]{处理动作}’ 文件列表(多个文件用空格隔开)

  -命令 | awk [选项] ‘[条件]{处理动作}’

处理数据的方式

  以行为处理单位。

  对数据进行逐行处理。

  处理完当前行,把当前行处理结果输出。

  在处理下一行,直到行尾。

awk应用

选项

-F   //指定分割列使用的符号,默认awk分割列使用的符号是空格和tab键

-f   //指定使用的awk脚本

处理动作:

awk内置变量

FILENAME   //当前处理的文件名

[root@localhost ~]# awk '{print FILENAME}' a.txt

$0   //保存当前处理的数据

[root@localhost ~]# awk '{print $0}' a.txt

NF   //用指定分隔符后,当前处理行的列数

[root@localhost ~]# awk –F “#” ‘{print NF}’ a.txt

NR   //保存awk当前处理行的行数

FNR   //当前处理行在文件中的行数

[root@localhost ~]# awk '{print NR,FNR}' a.txt   //多个变量用逗号间隔

[root@localhost ~]# awk '{print NR;print FNR}' a.txt   //多个处理动作分号间隔

[root@localhost ~]# awk '{print NF}{print FNR}' a.txt

FS   //与-F选项等效,指定分割列时使用的符号

[root@localhost ~]# awk 'BEGIN{FS=":";i=1}{print $1,$2,i}' a.txt

root x 1

bin x 1

daemon x 1

adm x 1

$1   //指定分割符后,保存第一列里数据

$2  二

[root@localhost ~]# awk '{print "asd"}' a.txt   //每读入一行打印“asd”

ENVIRON   //获取shell系统环境变量中的值

[root@localhost ~]# awk '{print ENVIRON[“USER”]}' a.txt

awk执行顺序

BEGIN{ }行前处理   //在读入行之前awk要执行的操作。

END{ }行后处理//awk把所有的行都读完之后要执行的操作写作END{ }里

[root@localhost ~]# awk -F ":" 'BEGIN{print NR}END{print NR}' /etc/passwd

0

33

awk处理条件

awk ‘条件{print $0}’文件列表

条件的表示方式:

1、正则表达式

  匹配 ~

[root@localhost ~]# awk -F ":" '$1~/root/{print $0}' a.txt

root:x:0:0:root:/root:/bin/bash

  不匹配 !~

[root@localhost ~]# awk -F ":" '$1!~/root/{print $0}' a.txt

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

2、数值比较

  ==   等于

  !=   不等于

  >   大于

  <   小于

  >=   大于等于

  <=   小于等于

[root@localhost ~]# awk -F ":" '$3==3{print $0}' a.txt

[root@localhost ~]# awk -F ":" '$1==”root”{print $0}' a.txt

[root@localhost ~]# awk -F ":" '$3>=50{print $1,$3}' /etc/passwd

nobody 99

3、字符比较   //字符用””引住

  ==    等于

  !=    不等于

4、逻辑比较

  &&   与

  ||   或

[root@localhost ~]# awk -F ":" '$3>=1&&$3<=10{print $1,$3}' /etc/passwd

bin 1

daemon 2

………

uucp 10

[root@localhost ~]# awk -F ":" '$3==1||$3==10{print $1,$3}' /etc/passwd

bin 1

uucp 10

5、运算符

+   -    *   /   %

++   --

+=   -=

系统有多少个用户

[root@localhost ~]# awk 'END{print "有用户 "NR" 个"}' /etc/passwd

有用户 33 个

[root@localhost ~]# awk 'BEGIN{i=0}{i++;i%2==0}END{print i}' /etc/passwd

33

把/etc/passwd偶数行输出

[root@localhost ~]# awk 'NR%2==0{print $0}' /etc/passwd

不能登入系统

[root@localhost ~]# awk -F ":" '$7~/nologin/{print $0}' /etc/passwd

1-100中是7的倍数和含有7的数

seq 100 | awk ‘$0%7==0||$0~/7/{print $0}’ |wc -l

练习:

[root@localhost ~]# awk -F ":" '$0~/[0-9]/{print $0}' a.txt   //行中有数字的输出

[root@localhost ~]# awk -F ":" '$0!~/[0-9]/{print $0}' a.txt//行中没数字的输出

awk流程控制

分支

  单分支

     if(条件表达式){动作1;动作2;动作n}

     if(条件表达式)动作1

[root@localhost ~]# awk -F ":" 'BEGIN{i=0}{if($3<=500)i++}END{print i}' /etc/passwd

  双分支

     if(条件表达式){

     动作1;动作2

     }

     else{

     动作1;动作2

     }

[root@localhost ~]# awk -F ":" 'BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i;print j}' /etc/passwd

[root@localhost ~]# cat test.awk

#!/bin/awk

BEGIN{

FS=":"

i=0

j=0

}

{

if ($3<=500){

i++

}

else{

j++

}

}

END{

print i

print j

}

[root@localhost ~]# awk -f test.awk /etc/passwd

32

1

  多分支

     if (条件表达式){

     动作1;动作2

     }

     else if (条件表达式){

     动作1;动作2

     }

     else if (条件表达式){

     动作1;动作2

     }

     …………………….

     else{

     动作1;动作2

     }

循环

  while (条件表达式){

  条件成立时执行的循环体

  }

输出uid<=10的用户详细信息

[root@localhost ~]# awk -F ":" '{while($3<=10){print $0;$3=11}}' /etc/passwd

  do{

  循环体

  ……………

  }while

  For (初值;条件表达式;步长){

  条件成立时执行的循环体

  }

输出系统的前3个用户

[root@localhost ~]# awk -F ":" '{for(i=NR;i<=3;i=4){print $1}}' /etc/passwd

root

bin

daemon

awk流程控制语句

break   跳出整个循环体

continue   结束本次循环,并开始下一个循环

next   让awk读取当前行的下一行

exit   终止awk读入行;如果有END{}就执行END{}里的动作,如果没有END{}就直接结束

awk数组

定义数组

  数组名[数组元素下标]=元素值

[root@localhost ~]# awk -F ":" '{for(i=1;i<=10;i=11){print $1}}' /etc/passwd

调用数组

  数组名[数组元素下标]

[root@www shell]# awk 'BEGIN{for(i=0;i<=10;i++){name[i]=i};for(j in name){print name[j]}}'

awk函数

1、length()  //返回字串长度

[root@localhost ~]# awk 'BEGIN{print length(ENVIRON["HOSTNAME"])}'

21’

[root@localhost ~]# awk -F ":" '{if(length($1)==4){print $1}}' /etc/passwd

root

sync

halt

2、match(m,n)   //字串匹配

m里与n匹配的字串,匹配成功返回true

[root@localhost ~]# awk -F ":" '{if(match($1,"^root$")){print $0}}'  /etc/passwd

root:x:0:0:root:/root:/bin/bash

[root@localhost ~]# awk -F ":" '{if(match($1,"s")){print $0}}'    /etc/passwd

sync:x:5:0:sync:/sbin:/bin/sync

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

news:x:9:13:news:/etc/news:

3、gsub(s,m,n)   //字串替换

把n中的s用m替换 替换成功返回true

[root@localhost ~]# awk -F ":" 'NR!=1{if(gsub("/sbin/nologin","/bin/bash",$7)){print $1,$7}}'  /etc/passwd

bin /bin/bash

daemon /bin/bash

adm /bin/bash

[root@localhost ~]# awk -F ":" '{if(match($1,"^root$")){print $0}}'  /etc/passwd

root:x:0:0:root:/root:/bin/bash

[root@localhost ~]# awk -F ":" '{if(match($1,"s")){print $0}}'    /etc/passwd

sync:x:5:0:sync:/sbin:/bin/sync

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

news:x:9:13:news:/etc/news:

4、index(m,n)   //字串搜索

n在m中第一次出现的位置 没有时返回值是0

[root@localhost ~]# awk  '{print index($0,"s") }'  /etc/passwd

30

21

5、split(s,m,n)   //分割字串

把s用n分割放到数组m里  返回值是数组元素个数

[root@localhost ~]# awk 'BEGIN{print split(ENVIRON["HOSTNAME"],pc,"."),pc[1]}'

2 localhost