awk
*注意: awk的表达式需要使用单引号''
awk:编辑器(主要处理有规律的文本)
程序模型:
打印:awk '{print}' a.txt
打印指定内容:awk '{print "hello",5}' a.txt
i++表示先赋值再加1
++i表示先加1再赋值
awk 'BEGIN{i=6}{print ++i}' a.txt
awk 'BEGIN{i=6}{print i++}' a.txt
BEGIN读入文本之前的操作
awk '{print i++}END{print "hhh"}' a.txt
END读入文本之后的操作
模式匹配:
当匹配到//里的正则表达式后才执行后面命令
awk '/aaa/{print ++i,"hhh"}' a.txt
打印第一个和第二个字段:$0表示所有
awk '{print $1,$2}' a.txt
指定字段变量:
awk 'BEGIN{a=2}{print $a}' a.txt
awk -F ';' '{}'
-F指定分隔符
\n 换行符
\t TAB键
\r 回车
表达式:
常量:数字和字符串型
字符串型在表达式中必须用引号括起来
字符串中可以使用转义序列,常用的转义序列有:
\n 换行 \t 水平制表符 \r 回车
赋值操作符:
++ i++=i+1
-- i--=i-1
+= i+=j i=i+j
-=
*=
/=
%=
^=
系统变量:
FS 输入定义字段分隔符,默认为一个空格field seprator
OFS 输出的字段分隔符,默认为一个空格
awk 'BEGIN{FS=":";OFS="T"}{print $1,$2}' a.txt
RS 输入记录分隔符,默认为一个换行符
ORS 输出的记录分隔符,默认为一个换行符
awk 'BEGIN{RS="\t";ORS=" "}{print $1,$2}' a.txt
NR 行数
awk '{print NR}' a.txt
FNR 行数,多文件操作时会重新排序
awk '{print FNR}' a.txt ming
NF 字段的个数,$NF表示最后一个字段
awk 'BEGIN{FS=":"}{print NF}' a.txt
FILENAME 文件名
awk '{print FILENAME}' a.txt
关系操作符和布尔操作符
关系操作符:
< 小于Less than
> 大于Greater than
<= 小于等于Less than or equal to
>= 大于等于Greater than or equal to
== 等于Equal to
NF==5 NF(每个输入记录的字段数)的值和5相比较,如果结果为真,那么就进行相应的处理,否则不进行处理。
!= 不等于Not equal to
~ 匹配Matches
$5~/MA/ {print $1 “,”$6}
!~ 不匹配Does not match
注意:关系操作符==和赋值操作符=是不同的
布尔操作符:
|| 逻辑或Logical OR
&& 逻辑与Logical AND
! 逻辑非Logical NOT
先执行关系操作符再执行布尔操作符
格式化打印:
printf ( format-expression [, arguments] )
c ASCII 字符
d 十进制整数
f 浮点格式
s 字符串
x 无符号十六进制
常用举例:
语法 %-width.precision format-specifier
printf(" %d \t %s \n ", $5 , $8 )
printf("|%10s|\n", "hello") 右对齐
printf("|%-10s|\n", "hello") 左对齐
printf("%*.*f\n", 5, 3, myvar) 宽度5 精度3 打印myvar
向脚本传递参数
var=root
awk –F: -v a=$var ‘$1==a {print}’ /etc/passwd
求阶乘
5!=5*4*3*2*1
影响控制流
break 退出循环
continue 终止当前的循环,并从循环的顶部开始一个新的循环
影响主输入循环
next 读入下一行,并返回脚本的顶部
exit 使主输入循环退出并将控制转移到END
ll |awk 'BEGIN{printf("%-5s\t%s\n"),"name","size";FS=" ";}/^-/{printf ("%-5s\t%s\n",$NF,$5);i+=$5}END{printf("%-5s\t%s\n"),"total",i}'
ll |awk 'BEGIN{printf("%-5s\t%s\n"),"name","size";print "============";FS=" ";}/^-/{printf ("%-5s\t%s\n",$NF,$5);i+=$5}END{print "=============";printf("%-5s\t%s\n"),"total",i}'
awk NR NF
NR (number of row)表示行
NF (number of field) 表示列(默认值为最后一列)
先来看一个实例:
获取剩余内存空间大小
[root@rhel6 ~]# free -m total used free shared buffers cached Mem: 3828 791 3037 0 110 494 -/+ buffers/cache: 186 3642 Swap: 5999 0 5999 [root@rhel6 ~]# free -m | awk 'NR==3 {print $NF}' 3642
NF-5 == -6也就是倒数第四列
[root@rhel6 ~]# free -m total used free shared buffers cached Mem: 3828 791 3037 0 111 494 -/+ buffers/cache: 186 3642 Swap: 5999 0 5999 [root@rhel6 ~]# free -m | awk 'NR==2 {print $(NF-5)}' 3828
awk -F
格式:-F'[:#/@¥$%]' 可以定义多个分隔符, 支持正则表达式 -F '[ :]+' 使用空格和:分割,+表示可以有连续的空格或:
用法:awk -F"[@/t]" '{print $1,$2,$3}' <test
以@,Tab键分割test文件的每一行,并输出第一、二、三列。
案例: 获取每个分区的Use空间
[root@rhel6 script]# df -Ph Filesystem Size Used Avail Use% Mounted on /dev/mapper/VG01-lv_root 3.8G 510M 3.1G 14% / tmpfs 1.9G 0 1.9G 0% /dev/shm /dev/sda1 477M 88M 364M 20% /boot /dev/mapper/VG01-lv_home 1.9G 3.7M 1.8G 1% /home /dev/mapper/VG01-lv_opt 1.9G 139M 1.7G 8% /opt /dev/mapper/VG01-lv_tmp 3.8G 7.9M 3.6G 1% /tmp /dev/mapper/VG01-lv_usr 4.7G 2.0G 2.6G 44% /usr /dev/mapper/VG01-lv_var 4.7G 509M 4.0G 12% /var [root@rhel6 script]# df -h | awk 'NR==3 {print $(NF-1)}' | awk -F '[%]' '{print $1}' 14
过滤出mysql端口
[root@rhel6 script]# netstat -lntup | grep 3306 | awk -F "[ :]+" '{print $5}' 3306 [root@rhel6 script]# netstat -lntup | grep 3306 tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 16463/mysqld
awk过滤
通过 /xxx|xxx|xxx/ 来进行过滤
[root@rhel6 script]# df -hP | awk -F '%' '/usr|tmp|var/{print $1}' tmpfs 1.9G 0 1.9G 0 /dev/mapper/VG01-lv_tmp 3.8G 81M 3.6G 3 /dev/mapper/VG01-lv_usr 4.7G 2.0G 2.5G 44 /dev/mapper/VG01-lv_var 4.7G 573M 3.9G 13 [root@rhel6 script]# df -hP | awk -F '%' '/usr|tmp|var/{print $2}' /dev/shm /tmp /usr /var