awk文本处理
介绍:awk编程语言/数据处理引擎
1、创造者:Aho、Weinberger、Kernighan
2、基于模式匹配检查输入文本,逐行处理并输出
3、通常用在Shell脚本中,获取指定的数据
4、单独用时,可对文本数据做统计
一、基本用法
1.语法格式
格式1:命令 | awk [选项] '[条件]{编辑指令}'
格式2:awk [选项] '[条件]{编辑指令}' 文件 .. ..
关于编辑指令
1、若有多条语句,可用分隔
2、print是最常用的指令
$ awk -F ":" '{print $1,$2}' /etc/passwd
root x
bin x
2.常用命令选项
-F:指定分隔符,可省略(默认空格或Tab位)
$ cat m.txt
111111 Shell
222 IT Test
$ awk '{print $1}' m.txt
11111111
2222
$ awk -F "e" '{print $1}' m.txt
11111111 Sh
2222 IT T
# 示例1:
$ df -hT /boot
$ df -hT /boot | tail -1
$ df -hT /boot | tail -1 | awk '{print $6}'
示例2:
$ head -5 /etc/passwd | awk -F: '{print $1,$7}'
3.awk内置变量
变量 | 用途 |
---|---|
FS | 保存或设置字段分隔符,例如FS=":" |
$n | 指定分隔的第n个字段,如$1、$3分别表示第1、第3列 |
NF | 记录当前处理行的字段个数(列数) |
NR | 记录当前已读入行的数量(行数) |
FNR | 保存当前处理行在原文本内的序号(行号) |
示例1:
$ awk '{print "第"FNR"行","有"NF"列"}' m.txt
第1行 有2列
第2行 有3列
$ awk '{print "Last:"$NF}' m.txt #每行最后一个字段
Last Shell
Last Test
$ awk -F: '$1==ENVIRON["USER"]{print $3}' /etc/passwd
0 # 输出当前用户的UID信息
4、awk处理的时机(三段操作,可单独使用,也可以一起使用)
1)行前处理,BEGIN{}
读入第一行文本之前执行
一般用来初始化操作
2)逐行处理,{}
逐行读入文本执行相应的处理
是最常见的编辑指令块
3)行后处理,END{}
处理完最后一行文本之后执行
一般用来输出处理结果
# 示例: 预处理不需要的数据文件
$ awk 'BEGIN {a=34;print a+12}'
# 统计使用bash的用户个数
$ awk 'BEGIN{x=0}/\<bash$/{x++} END{print x}' /etc/passwd
59
# 预处理时,行数为0
# 全部处理完以后,行数为已读入的行
$ awk 'BEGIN {print NR} END{print NR}' m.txt
0
2
二、awk处理条件
条件如何表示?
格式回顾
awk [选项] '[条件]{编辑指令}' 文件 .. ..
条件的表现形式
正则表达式
数值/字符串比较
逻辑比较
运算符
1.使用正则条件
基本格式
/正则表达式/
~ 匹配 !~不匹配
//列出一ro开头的记录
$ awk -F: '/^ro/{print}' /etc/passwd //默认打印整行($0)
root:x:0:0:root:/root:/bin/bash
//列出第7个字段不以bash结尾的用户名、登录Shell
$ awk -F: '$7!~/bash$/{print $1, $7}' /etc/passwd
bin /sbin/nologin
daemon /sbin/nologin
2.使用数值比较
数值比较
==等于、!=不等于
>大于、>=大于等于
<小于、<=小于等于
$ cat reg.txt
abcd XX
XX
abcabcd XX
# 输出第2行文本
$ awk 'NR==2{print}' reg.txt
XX
# 输出第2列不是XX的行
$ awk '$2!="XX"{print}' reg.txt
XX
# 输出含2个及以上字段的行
$ awk 'NF>=2{print}' reg.txt
abcd XX
abcabcd XX
3.多个条件的组合
逻辑比较测试
&&逻辑与:期望多个条件都成立
||逻辑或:只要有一个条件成立即满足要求
# 列出UID(对应$3)小于2的用户信息
$ awk -F: '$3>=0&&$3<2{print $1, $3}' /etc/passwd
root 0
bin 1
# 列出UID(对应$3)为1或7的用户信息
$ awk -F: '$3==1||$3==7{print $1, $3}' /etc/passwd
bin 1
halt 7
$ awk -F: '$7~/bash$/&&$3>=200{print $1, $3, $7}' /etc/passwd
4.变量的运算
运算符
+ - * / %
++ -- += -= *= /=
// 输出奇数行文本
$ awk 'NR%2==1{print}' reg.txt
abcd XX
abcabcd XX
# 统计文本的总字段个数
$ awk 'BEGIN{i=0} {i+=NF} END{print i}' reg.txt
5
# 计算能同时被3和13整除的整数个数
$ seq 200 | awk 'BEGIN{i=0} ($0%3==0)&&($0%13==0){i++} END{print i}'
5
注1:seq 生成整数序列(sequence)
注2:awk在过滤文本时,并不影响文件本身的内容,只将内容做过滤并输出,并不能修改原文件