Awk文本处理
awk
是一种编程语言,用于在linux/unix
下对文本和数据进行处理。awk
数据可以来自标准输入、一个或多个文件,或其它命令的输出。awk
通常是配合脚本进行使用, 是一个强大的文本处理工具。
Awk 工作原理
# awk -F: '{print $1,$3}' /etc/passwd
1.awk将文件中的每一行作为输入, 并将每一行赋给内部变量$0
, 以换行符结束
2.awk开始进行字段分解,每个字段存储在已编号的变量中,从$1
开始[默认空格分割]
3.awk默认字段分隔符是由内部FS
变量来确定, 可以使用-F
修订
4.awk行处理时使用了print
函数打印分割后的字段
5.awk在打印后的字段加上空格,因为$1,$3
之间有一个逗号。逗号被映射至OFS
内部变量中,称为输出字段分隔符, OFS
默认为空格.
6.awk输出之后,将从文件中获取另一行,并将其存储在$0
中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕.
Awk内部变量
1.$0
保存当前记录的内容
[root@Shell ~]# awk '{print $0}' /etc/passwd
2.NR
记录输入总的编号(行号)
[root@Shell ~]# awk '{print NR,$0}' /etc/passwd [root@Shell ~]# awk 'NR<=3' /etc/passwd
3.FNR
当前输入文件的编号(行号)
[root@Shell ~]# awk '{print NR,$0}' /etc/passwd /etc/hosts [root@Shell ~]# awk '{print FNR,$0}' /etc/passwd /etc/hosts
4.NF
保存行的最后一列
[root@Shell ~]# awk -F ":" '{print NF,$NF}' /etc/passwd /etc/hosts
5.FS
指定字段分割符, 默认是空格
//以冒号作为字段分隔符 [root@Shell ~]# awk -F: '/root/{print $1,$3}' /etc/passwd [root@Shell ~]# awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd //以空格冒号tab作为字段分割 [root@Shell ~]# awk -F'[ : ]' '{print $1,$2,$3}' /etc/passwd
6.OFS
指定输出字段分隔符
//,逗号映射为OFS, 初始情况下OFS变量是空格 [root@Shell ~]# awk -F: '/root/{print $1,$2,$3,$4}' /etc/passwd [root@Shell ~]# awk 'BEGIN{FS=":"; OFS="+++"} /^root/{print $1,$2}' /etc/passwd
7.RS
输入记录分隔符,默认为换行符[了解]
[root@Shell ~]# awk -F: 'BEGIN{RS=" "} {print $0}' /etc/hosts
8.ORS
将文件以空格为分割每一行合并为一行[了解]
[root@Shell ~]# awk -F: 'BEGIN{ORS=" "} {print $0}' /etc/hosts
9.print
格式化输出函数
[root@Shell ~]# date|awk '{print $2,"5月份"" ",$NF,"今年"}' [root@Shell ~]# awk -F: '{print "用户是:" $1 " 用户uid: " $3 " 用户gid:" $4}' /etc/passwd printf 函数 [root@Shell ~]# awk -F: '{printf "%-15s %-10s %-15s ", $1, $2, $3}' /etc/passwd %s 字符类型 %d 数值类型 占 15 字符 - 表示左对齐,默认是右对齐 printf 默认不会在行尾自动换行,加
Awk模式动作
awk语句都由模式和动作组成。
模式部分决定动作语句何时触发及触发事件。
如果省略模式部分,动作将时刻保持执行状态。模式可以是条件语句或复合语句或正则表达式。
1.正则表达式
//匹配记录(整行) [root@Shell ~]# awk '/^root/' /etc/passwd [root@Shell ~]# awk '$0 ~ /^root/' /etc/passwd //匹配字段:匹配操作符(~ !~) [root@Shell ~]# awk '$1~/^root/' /etc/passwd [root@Shell ~]# awk '$NF !~ /bash$/' /etc/passwd
2.比较表达式
比较表达式采用对文本进行比较,只有当条件为真,才执行指定的动作。
比较表达式使用关系运算符,用于比较数字与字符串。
关系运算符
运算符 含义 示例 < 小于 x<y <= 小于或等于 x<=y == 等于 x==y != 不等于 x!=y >= 大于等于 x>=y > 大于 x>y //uid为0的列出来 [root@Shell ~]# awk -F ":" '$3==0' /etc/passwd //uid小于10的全部列出来 [root@Shell ~]# awk -F: '$3 < 10' /etc/passwd //用户登陆的shell等于/bin/bash [root@Shell ~]# awk -F: '$7 == "/bin/bash" ' /etc/passwd //第一列为alice的列出来 [root@Shell ~]# awk -F: '$1 == "alice" ' /etc/passwd //为alice的用户列出来 [root@Shell ~]# awk -F: '$1 ~ /alice/ ' /etc/passwd [root@Shell ~]# awk -F: '$1 !~ /alice/ ' /etc/passwd //磁盘使用率大于多少则,则打印可用的值 [root@Shell ~]# df |awk '//$/'|awk '$3>1000000 {print $4}'
3.条件表达式
[root@Shell ~]# awk -F: '$3>300 {print $0}' /etc/passwd [root@Shell ~]# awk -F: '{if($3>300) print $0}' /etc/passwd [root@Shell ~]# awk -F: '{if($3>5555){print $3} else {print $1}}' /etc/passwd
4.运算表达式
[root@Shell ~]# awk -F: '$3 * 10 > 500000' /etc/passwd [root@Shell ~]# awk -F: 'BEGIN{OFS="--"} { if($3*10>50000) {print $1,$3} } END {print "打印ok"}' /etc/passwd [root@Shell ~]# awk '/southem/{print $5 + 10}' datafile [root@Shell ~]# awk '/southem/{print $5 + 10.56}' datafile [root@Shell ~]# awk '/southem/{print $8 - 10}' datafile [root@Shell ~]# awk '/southem/{print $8 / 2 }' datafile [root@Shell ~]# awk '/southem/{print $8 * 2 }' datafile [root@Shell ~]# awk '/southem/{print $8 % 2 }' datafile
5.逻辑操作符和复合模式
&&逻辑与 || 逻辑或 !逻辑非 //匹配用户名为root并且打印uid小于15的行 [root@Shell ~]# awk -F: '$1~/root/ && $3<=15' /etc/passwd //匹配用户名为root或uid大于5000 [root@Shell ~]# awk -F: '$1~/root/ || $3>=5000' /etc/passwd
awk
示例1(知道每个命令都是什么含义就好)
# awk '/west/' datafile # awk '/^north/' datafile # awk '$3 ~ /^north/' datafile # awk '/^(no|so)/' datafile # awk '{print $3,$2}' datafile # awk '{print $3 $2}' datafile # awk '{print $0}' datafile # awk '{print "Number of fields: "NF}' datafile # awk '/northeast/{print $3,$2}' datafile # awk '/^[ns]/{print $1}' datafile # awk '$5 ~ /. [7-9]+/' datafile # awk '$2 !~ /E/{print $1,$2}' datafile # awk '$3 ~ /^Joel/{print $3 "is a nice boy."}' datafile # awk '$8 ~ /[0-9][0-9]$/{print $8}' datafile # awk '$4 ~ /Chin$/{print "The price is $" $8 "."}' datafile # awk '/Tj/{print $0}' datafile # awk -F: '{print "Number of fields: "NF}' /etc/passwd # awk -F"[ :]" '{print NF}' /etc/passwd
awk示例2
[root@Shell ~]# cat b.txt bgx xuliangwei:is a:good boy! [root@Shell ~]# awk '{print NF}' b.txt 4 [root@Shell ~]# awk -F ':' '{print NF}' b.txt 3 [root@Shell ~]# awk -F"[ :]" '{print NF}' b.txt 6
Awk条件判断
if语句格式:{ if(表达式){语句;语句;... }}
//打印当前管理员用户名称 [root@Shell ~]# awk -F: '{ if($3==0){print $1 "is adminisitrator"} }' /etc/passwd //统计系统用户数量 [root@Shell ~]# awk -F: '{ if($3>0 && $3<1000){i++}} END {print i}' /etc/passwd //统计普通用户数量 [root@Shell ~]# awk -F: '{ if($3>1000){i++}} END {print i}' /etc/passwd
if...else 语句格式: {if(表达式){语句;语句;... }else{语句;语句;...}}
# awk -F: '{if($3==0){print $1} else {print $7}}' /etc/passwd # awk -F: '{if($3==0) {count++} else{i++} }' /etc/passwd # awk -F: '{if($3==0){count++} else{i++}} END{print " 管理员个数: "count ; print " 系统用户数: "i}' /etc/passwd
if...else if...else 语句格式:
[root@Shell ~]# awk -F: '{ if($3==0){i++} else if($3>0 && $3<1000){j++} else if($3>1000) {k++}} END {print i;print j;print k}' /etc/passwd [root@Shell ~]# awk -F: '{ if($3==0){i++} else if($3>0 && $3<1000){j++} else if($3>1000) {k++}} END {print "管理员个数"i; print "系统用户个数" j; print "系统用户个 数" }' /etc/passwd 管理员个数1 系统用户个数29 系统用户个数69
Awk循环语句
while循环
[root@Shell ~]# awk 'BEGIN{ i=1; while(i<=10){print i; i++} }' [root@Shell ~]# awk -F: '{i=1; while(i<=NF){print $i; i++}}' /etc/passwd [root@Shell ~]# awk -F: '{i=1; while(i<=10) {print $0; i++}}' /etc/passwd [root@Shell ~]#cat b.txt 111 222 333 444 555 666 777 888 999 [root@Shell ~]# awk '{i=1; while(i<=NF){print $i; i++}}' b.txt
for循环
//C 风格 for [root@Shell ~]# awk 'BEGIN{for(i=1;i<=5;i++){print i} }' //将每行打印 10 次 [root@Shell ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd [root@Shell ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd [root@Shell ~]# awk -F: '{ for(i=1;i<=NF;i++) {print $i} }' passwd
awk数组实战
未完。。。。。