awk—》文本处理–》根据条件去截取字段
awk难点:
1.正则表达
2.if
3.内置函数
4.内置变量
5.for,数组array
AWK 默认的分隔符是空白(空格、tab)
输入分隔符 -F
输出分隔符 ,
$1 代表第1个字段
$2 代表第2个字段
以此类推
$0 代表整行
正则表达式和bash一致
数学运算符:+,-,*,/,%,++,–
逻辑关系符:&&,||,!
比较操作符:>,<,>=,!=,<=,,,!
文本数据表达式:(精确匹配) ~表示匹配后面的模式(模糊匹配)
who |awk '$2~ /pts/{print $1}'
awk -F: '$3~/\<...\>/ {print $1,$3}' /etc/passwd
print 是awk里的输出命令
, 是分隔符号
‘{}’ 是固定语法
NF 每行$0的字段数
NR 当前处理的行号
RS为输入记录分隔符(行分隔符)
FS为输入字段分隔符号(列分隔符)
ORS、OFS为相对应的输出分隔符O=out
awk里的变量的传参问题和shell脚本的传参问题
shell里的变量传递到awk里的问题
1.awk -v
[root@localhost ~]# sg="panjinhao"
[root@localhost ~]# echo|awk -v bsg=$sg '{print bsg}'
panjinhao
[root@localhost ~]# bash xiexy.sh root
1 root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# bash -x xiexy.sh root
+ awk -v var=root -F: '$1==var{print NR,$0}' /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# cat xiexy.sh
#!/bin/bash
awk -v var=$1 -F: '$1==var{print NR,$0}' /etc/passwd
2.或者使用双引号,是awk内部的$0 1 等 1 等 1等符号前需要使用\转义
[root@localhost ~]# mv="zhangjie"
[root@localhost ~]# useradd zhangjie_123
[root@localhost ~]# cat /etc/passwd|awk -F: "/^$mv/{print $1,$3}"
awk: 命令行:1: /^zhangjie/{print ,}
awk: 命令行:1: ^ syntax error
awk: 命令行:1: /^zhangjie/{print ,}
awk: 命令行:1: ^ syntax error
awk: 命令行:1: /^zhangjie/{print ,}
awk: 命令行:1: ^ 未预期的新行或字符串结束
[root@localhost ~]# cat /etc/passwd|awk -F: "/^$mv/{print \$1,\$3}"
zhangjie_123 1062
3.可以在BEGIN部分定义,整个处理的过程都可以使用,END部分也可以使用
cat /etc/passwd |awk 'BEGIN{OFS="###";FS=":"}{print $1,$3}'
4.使用单引号,将变量引起来,然后前面加一个$符号再次引用变量的值,相当于取2次值
sg=3
awk -F : '/root/{print $1,$'$sg'}' /etc/passwd
awk里的if语句
1.单分支
if (condition) statement
awk -F: '{if($1~/\<...\>/)print $0}' /etc/passwd
2.多分支
if (表达式 ) {
语句;语句;...
} else if (表达式 ) {
语句;语句;...
} else if (表达式 ) {
语句;语句;...
} else {
语句;语句;...
}
$ awk {
if ( $3 > 89 && $3 < 101 ) a ++
else if ( $3 > 79 ) b ++
else if ( $3 > 69 ) b ++
else if ( $3 > 59 ) be ++
else f ++
}END {
print "The number of failures is "f
} filename
awk -F: '{if ($1=="root") print $1;else print $NR}' /etc/passwd
awk的for 循环格式
for (i=0;i<10;i++){print $i;}
for (i in array){print array[i]}
awk里的数组
awk里如何使用数组来存放数据?
待更。。。
练习
cat c.txt |tail -3|awk -F, '$NF !=0 {print $0,sqrt(int($NF/100)*int($NF/100)),length($1)}'
cat /etc/passwd|awk -F: 'BEGIN{print "##start##"} /bash$/{print $1,$7}END{print "##end##"}'
[root@localhost lianxi]# who |awk '{print "time:"$4,"name:"$2}'
time:15:02 name:tty1
time:15:33 name:pts/0
cat /etc/passwd|tail -1|awk -F[:/] '{print $8}'
#-F[:/]指定分割符为:或者/
awk -F: '$3 ~ /\<.{3}\>/ {print $1,$3}' /etc/passwd
awk -F: '$3 ~ /\<...\>/ {print $1,$3}' /etc/passwd
#\<.{3}\ \<...\> 匹配为三大字母组成的
cat /etc/passwd|awk 'FS=":";OFS="#"{print NR,$0,$NF}'
#推荐使用-F指定输入分隔符
使用NF变量显示passwd文件倒数第二列的内容
cat passwd |awk -F: '{print $(NF-1)}'
显示passwd文件中第5到第10行的用户名
[root@localhost lianxi]# cat passwd|awk -F: '{print $1,NR}'|head -10 |tail -5
显示passwd文件中第7列不是bash的用户名
cat passwd |awk -F: '/[^bash]/{print $7}'
显示passwd文件中行号是5结尾的行号和行
cat passwd |awk 'NR%10==5 {print NR,$NF}'
用ip add只显示ip(不能使用tr或者cut命令)
ip add |egrep "inet " |awk '{print $2}'
先使用ifconfig,使用awk显示eth0的入站流量和出站流量(字节)
ifconfig |head -8|awk '$0 ~/RX.*bytes|TX.*bytes/{print $5}'
使用awk命令统计以r开头的用户数目,显示如下效果
cat passwd |awk -F: 'BEGIN{i=0} $1 ~/^r/{print $1,$i++} END{ print i}'
/etc/passwd ,$3 是uid 用户的编号,如果用户的编号是0 --》管理员,1~999 --》程序用户
,大于1000 ---》普通用户,最后统计出有多少管理员,多少程序用户,多少普通用户?
awk -F: 'BEGIN{a=b=c=0}{if($3==0)print "管理员",a++;else if($3>=1&&$3<=999)print "程 序用户",b++;else if($3>1000)print "普通用户",c++}END{print "管理员有个"a,"程序用户有个"b,"普通用户有 个"c}' /etc/passwd