Awk基础

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数组实战

未完。。。。。

 
原文地址:https://www.cnblogs.com/tim1blog/p/9709524.html