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