awk工作模式介绍
-
简介
awk
是一个文本处理工具,通常用于处理数据并生成结果报告awk
的命名是它的创始人Alfred Aho 、Peter Weinberger、和Brian Kernighan姓氏的首个字母组成。
-
工作模式
-
语法格式:
-
awk 'BEGIN{}pattern{commonds}END{}' file_name
-
standard output | awk 'BEGIN{}pattern{commonds}END{}'
-
语法格式说明
语法格式 解释 BEGIN{}
正式处理数据之前执行 pattern
匹配模式 {commands}
处理命令,可能多行 END{}
处理完所有匹配数据后执行
-
awk的内置变量
-
内置变量对照表
内置变量 含义 $0 整行内容 1 1~ 1 n 当前行的1~n个字段 NF
当前行的字段个数,也就是有多少列 NR
当前行的行号,从1开始计数 FNR
多文件处理时,每个文件行号单独计数,都是从0开始 FS
输入字段分隔符。不指定默认为空格或tab键分割 RS
输入行分隔符。默认回车换行(\n) OFS
输出字段分隔符。默认为空格 ORS
输出行分隔符。默认为回车换行 FILENAME
处理文件的文件名 ARGC
命令行参数个数 ARGV
命令行参数数组 -
例1:
-
例2:
awk格式化输出之printf
-
printf的格式说明符
格式符 %s
打印字符串 %d
打印十进制数 %f
打印一个浮点数 %o
打印八进制数 %e
打印数字的科学计数法形式 %x
打印十六进制数 %c
打印单个字符的ASCII码 -
左对齐 +
右对齐 #
显示8进制在前面加0,显示16进制在前面加0x -
示例:
-
以字符串格式打印/etc/passwd中的第7个字段,以":"作为分隔符
awk 'BEGIN{FS=":";OFS=":"}{printf "%s",$7}' /tec/passwd
-
以10进制格式打印/etc/passwd中的第三个字段,以":"作为分隔符
awk 'BEGIN{FS=":";}{printf "%d",$3}' /etc/passwd
-
以浮点数格式打印/etc/passwd中的第三个字段,以":"作为分隔符
awk 'BEGIN{FS=":";}{printf "%6.2f",$3}' /etc/passwd
-
以16进制数格式打印/etc/passwd中的第三个字段,以":"作为分隔符
awk 'BEGIN{FS=":";}{printf "%x",$3}' /etc/passwd
-
以8进制数格式打印/etc/passwd中的第三个字段,以":"作为分隔符
awk 'BEGIN{FS=":";}{printf "%o",$3}' /etc/passwd
-
以科学计数法格式打印/etc/passwd中的第三个字段,以":"作为分隔符
awk 'BEGIN{FS=":";}{printf "%.2e",$3}' /etc/passwd
-
awk模式匹配的两种工作模式
-
模式匹配的两种用法
- 第一种:
RegExp
- 第二种:关系运算匹配
- 第一种:
-
用法格式对照表
语法格式 含义 RegExp 按正则表达式匹配 关系运算 按关系运算匹配 -
关系运算符匹配
运算符 含义 < 小于 > 大于 <= 小于等于 >= 大于等于 == 等于 != 不等于 ~ 匹配正则表达式 !~ 不匹配正则表达式 -
RegExp匹配
-
将/etc/passwd中包含root的行输出
awk 'BEGIN{FS=":";}/root/{print $0}' /etc/passwd
-
将/etc/passwd中以yarn开头的行输出
awk 'BEGIN{FS=":";}/^yarn/{print $0}' /etc/passwd
-
-
布尔运算符匹配
|| 或 && 与 ! 非 -
范例:
-
以:为分隔符,匹配/etc/passwd文件中第三个字段小于50的行所有信息
awk 'BEGIN{FS=":"}$3<50{print $0} /etc/passwd'
-
以:为分隔符,匹配/etc/passwd文件中第三个字段大于50的行所有信息
awk 'BEGIN{FS=":"}$3>50{print $0} /etc/passwd
-
以:为分隔符,匹配/etc/passwd文件中第7个字段为/bin/bash的行所有信息
awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd
-
以:为分隔符,匹配/etc/passwd文件中第7个字段为/bin/bash的行所有信息
awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' /etc/passwd
-
以:为分隔符,匹配/etc/passwd文件中第三个字段有3个数字的行所有信息
awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/' /etc/passwd
-
以:为分隔符,匹配/etc/passwd文件中的行中没有/sbin/nologin的
awk 'BEGIN{FS=":"}$0!~/\/sbin\/nologin/{print $0}' /etc/passwd
-
以:为分隔符,匹配/etc/passwd中包含hdfs或yarn的所有行信息
awk 'BEGIN{FS=":"}$1=="hdfds" || $1=="yarn" {print $0}' /etc/passwd
-
以:为分隔符,匹配/etc/passwd中第三个字段小于50并且第四个字段大于50的所有行信息
awk 'BEGIN{FS=":"}$3<50 && $4>50 {print $0}' /etc/passwd
-
awk动作中的表达式用法
-
awd动作表达式中的算术运算符
运算符 含义 + - * / % ^或** 乘方 ++x x++ –x x– -
范例:
-
使用awk计算/etc/services中的空白行的数量
awk 'BEGIN{sum=0;}/^$/{sum++;}END{print sum;}' /etc/services
-
计算/etc/passwd文件中第三个字段的平均值
awk 'BEGIN{FS=":";sum=0;count=0;}{sum=sum+$3;count++}END{print sum/count}' /etc/passwd
-
awk动作中的条件及循环语句
-
条件语句
if (条件表达式){ 动作1 } else if (条件表达式){ 动作2 } else{ 动作3 }
-
范例:
-
循环语句
do{ 动作 }while(条件表达式)
for(初始化计数器;计数器测试;计数器变更){ 动作 }
while(条件表达式){ }
-
范例:
计算1+2+3+……+100的和
#for循环实现 BEGIN{ sum=0; for(i=1;i<101;i++) { sum+=i; } printf "%s=%d","1+2+3+……+100",sum } //while循环实现 BEGIN{ sum=0; idx=1; while(idx<=100){ sum=sum+idx; } printf "%s=%d","1+2+3+……+100",sum } #do while实现 BEGIN{ sum=1; idx=1; do{ idx++; sum=sum+idx; }while(idx<100) printf "%s=%d","1+2+3+……+100",sum }
awk中的字符串函数
函数名 | 解释 | 函数返回值 |
---|---|---|
length(str) | 计算中字符串的长度 | 整数长度值 |
index(str1,str2) | 在str1中查找str2的位置 | 返回值为位置索引 |
tolower(str) | 转换为小写 | 转换后的小写字符串 |
toupper(str) | 转换为大写 | 转换后的大写字符串 |
substr(str) | 从字符串的m个位置开始,截取n位 | 截取后的子串 |
split(str,arr,fs) | 按fs切割字符串,结果保存arr | j截取后字串的个数 |
match(str,RE) | 在str中按照RE查找,返回位置 | f返回索引位置 |
sub(RE,RepStr,str) | 在str中搜索符合RE的字串,将其替换为RepStr,只替换第一个 | 替换的个数 |
gsub(RE,RepStr,str) | 在str中搜索符合RE的字串,将其替换为RepStr,只替换所有 | 替换的个数 |
-
范例:
-
以:为分隔符,返回/etc/passwd中每行中每个字段的长度
-
搜索字符串"I have a dream"中出现"ea"字符串的位置
-
搜索字符串"Tranction 2345 Start:Select * from master" 第一个数字出现的位置
-
截取字符串"tranaction start"的字串,从第4个字符开始,截取5位
-
替换字符串"Tranction 234 Start,Event ID:9002"中第一个匹配到的数字为$
awk 'BEGIN{str="Tranction 234 Start,Event ID:9002";sub(/[0-9]+/,"\$",str);print str}'
-
awk中的常用选项
选项 | 解释 |
---|---|
-v | 参数传递 |
-f | 指定脚本文件 |
-F | 指定分隔符 |
-V | 查看awk的版本号 |
- 范例:
- 例1:
awk -v var1="hellow world" 'BEGIN{num=666;print num,var1}'
- 例2:
awk -F : '{print $1}' /etc/passwd
- 例1:
awk中数组的用法
-
定义一个数组
awk 'EGIN{arr[1]="ZhangSan1";arr[2]="ZhangSan2";arr[3]="ZhangSan3"};print arr[2]'
-
awk数组的下标不仅仅可以是数字,还可以是任意字符串,其实,awk中的数组本来就是关联数组,但用数字做下标时,awk也会默认把数字下标转换成字符串,所以它本质上还是一个使用字符串作为下标的***关联数组***。
-
删除数组中的元素
delete arr[1];delete arr
-
判断元素是否为空(数组的元素设置为空,是允许的,当数组中没有某个元素而直接引用它的时候,它默认被赋值为空)
awk 'EGIN{arr[1]="ZhangSan1";arr[2]="ZhangSan2";arr[3]="ZhangSan3"};if(3 in arr) print "three"
-
数组的遍历
awk 'EGIN{arr[1]="ZhangSan1";arr[2]="ZhangSan2";arr[3]="ZhangSan3"};for (i in arr) {print arr[i]}'
-
在awk中,字符串和空字符串在参与运算时也会被当做数字0,之前我们说过,当我们引用数组中一个不存在的元素,元素被赋值成空字符串,当对这个元素进行自加运算时,元素的值就变成了1,因此当我们对一个不存在的元素进行自加运算后,这个元素的值就变成了自加的次数,自加x次,元素的值就被赋值为x,自加y次元素的值就被赋值为y,所以我们可以通过awk数组的这个特性来统计文本中某字符串出现的次数。
#统计文本中人名出现的次数、 awk '{for(i=1;i<=NF;i++){count[$i]++} }END{for(j in count)\ {print j , count[j]}}' text
shell中数组的用法
-
定义一个数组:
arr={"Allen" "Mike" "Messi" "Jerry" "Hanmeimei" "WangLin"}
-
打印元素
echo ${arr[2]}
-
打印元素的个数
echo ${#arr[@]}
-
打印元素的长度
echo ${#arr[3]}
-
给元素赋值
arr[4]="LiSi"
-
删除元素
unset arr[2];unset arr
-
分片访问
echo ${arr[@]:1:3}
-
元素内容替换
${arr[@/e/E]}
只替换第一个e;${arr[@//e/E]}
替换所有的e -
数组的遍历
for a int arr do echo $a done
-
注意:
-
shell中的数组下标是从0开始的
-
@
和*
在数组中都可以表示匹配所有元素 -
#
表示其后元素的长度 -
当我们使用
unset
删除数组中的单个元素时,其他元素还是使用初始的下标arr={"aaa" "bbb" "ccc" "ddd" "eeee"} echo ${arr[1]} unset arr[0] echo ${arr[1]}
-