awk是一个文本处理工具,通常用于处理数据并生成结构报告。
语法格式:
第一种形式:awk 'BGGIN{}pattern{commands}END{}' file_name
第二种形式:standard output | awk 'BGGIN{}pattern{commands}END{}' file_name
说明:
BEGIN{} 正式处理数据之前执行
pattern{} 匹配模式
{commands} 处理命令,可能多行
END{} 处理完所有匹配数据后执行
awk选项
选项 | 说明 |
---|---|
-v | 参数传递 |
-f | 指定脚本文件 |
-F | 指定分隔符 |
-V | 查看awk版本号 |
如:
# -v
[root@VM_0_14_centos test]# num=10
[root@VM_0_14_centos test]# var=20
[root@VM_0_14_centos test]# awk -v num1="$num" -v num2="$var" 'BEGIN{print num1,num2}'
# -f
[root@VM_0_14_centos test]# num=10
[root@VM_0_14_centos test]# var=20
[root@VM_0_14_centos test]# awk -v num1="$num" -v num2="$var" -f test.awk
# -F
[root@VM_0_14_centos test]# awk -F ":" '{print $1}' /etc/passwd
注:在引用变量的时候,最好加双引号""
内置变量
$0 整行内容
[root@VM_0_14_centos test]# awk '{print $0}' test.txt
$1-$n 当前行的第 1 - n 个字段(默认 冒号: / tab键 切割)
[root@VM_0_14_centos test]# awk '{print $2}' test.txt
NF 当前行的字段个数,也就是有多少列
[root@VM_0_14_centos test]# awk '{print NF}' test.txt
输出每行中最大的字段(一列)$NF
[root@VM_0_14_centos test]# awk '{print $NF}' test.txt
NR 当前行的行号,从 1 开始计数
[root@VM_0_14_centos test]# awk '{print NR}' test.txt
FNR 多文件处理时,每个文件行号单独计数,都是从 0 开始
[root@VM_0_14_centos test]# awk '{print FNR}' test.txt
FS 输入字段分隔符,不指定默认以空格或 tab 键分割
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":"}{print $0}' test.txt
RS 输入行分隔符,默认回车换行
[root@VM_0_14_centos test]# awk 'BEGIN{RS="--"}{print $0}' test.txt
OFS 输出字段(列)分隔符,默认为空格
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":";OFS='&'}{print $1,$2}' test.txt
ORS 输出行分隔符,默认为回车换行
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":";OFS="&";ORS="@"}{print $1,$2}' test.txt
FILENAME 当前输入的文件名字
[root@VM_0_14_centos test]# awk '{print FILENAME}' test.txt
ARGC 命令行参数个数
[root@VM_0_14_centos test]# awk '{print ARGC}' test.txt
ARVG 命令行参数数组
printf
printf
与print
都是输出,只不过,print
有默认的分隔符(空格 / tab键),而printf
没有默认的分割符,且还能美化输出(如:左对齐 / 右对齐)
printf
格式说明符:
%s 打印字符串
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%-20s %-20s\n",$1,$7}' test.txt
说明:%20s:是占20个字符,在20字符后再输出第二个字段值 $7;且两个 %s 之间有空格,表示输出的两个字段 $1 $7直接以空格间隔。\n是一次完整的输出后,回车换行显示第二次完整输出。减号(-) 是左对齐显示输出
%d 打印十进制数
%f 打印一个浮点数
%x 打印打印十六进制数
%o 打印八进制数
%e 打印数字的科学计数法形式
%o 打印单个字符的 ASCLL码
printf
格式修饰符:
- 左对齐
+ 右对齐
# 显示8进制或16进制在前面加 #
示例:
- 以字符串格式打印 test.txt 中的第7个字段,以 : 作为分隔符
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%s\n",$7}' test.txt
- 以10进制格式打印 test.txt 中的第3个字段,以 : 作为分隔符
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%d\n",$3}' test.txt
- 以浮点数格式打印 test.txt 中的第3个字段,以 : 作为分隔符
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%0.2f\n",$3}' test.txt
说明:0.2 是保留2位小数
- 以16进制格式打印 test.txt 中的第3个字段,以 : 作为分隔符
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%#x\n",$3}' test.txt
说明:# 显示8进制或16进制在前面加 #
- 以8进制格式打印 test.txt 中的第3个字段,以 : 作为分隔符
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%#o\n",$3}' test.txt
- 以科学计数法格式打印 test.txt 中的第3个字段,以 : 作为分隔符
[root@VM_0_14_centos test]# awk 'BEGIN{FS=":"} {printf "%e\n",$3}' test.txt
awk匹配模式
1. RegExp
如:1. 匹配 /etcpasswd 文件行中含有 root 字符串的所有行
[root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd
如:2. 匹配 /etcpasswd 文件行中以 root 开头的所有行
[root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}/^root/{print $0}' /etc/passwd
2. 运算符匹配
关系运算符
运算符 | 说明 |
---|---|
< | (小于) |
> | (大于) |
<= | (小于等于) |
>= | (大于等于) |
== | (等于) |
!= | (不等于) |
~ | (匹配正则表达式) |
!= | (不匹配正则表达式) |
如:1. 匹配 /etc/passwd 文件中第 3 个字段(数值)小于50的所有行信息
[root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd
如:2. 匹配 /etc/passwd 文件中第 7 个字段为 /bin/bash 的所有行信息
[root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd
-
布尔运算符
匹配
运算符 | 说明 |
---|---|
|| | 或 |
&& | 与 |
! | 非 |
如:1. 匹配 /etc/passwd 文件中包含 sync 或 root 的所有行信息
[root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}$1=="root" || $1=="sync"{print $0}' /etc/passwd
如:2. 匹配 /etc/passwd 文件中第3个字段小于50 且第 4 个字段大于50的所有行信息
[root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}$3<50 && $4>50{print $0}' /etc/passwd
- 动作表达式中的
算术运算符
运算符 | 说明 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 模 |
^ 或 ** | 乘方 |
++x | 在返回 x 变量之前,x 变量加1 |
x++ | 在返回 x 变量之后,x 变量加1 |
如:
# 加 +
// num2未定义就是 0
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2+=num1;print num1,num2}'
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1+num2}'
# 减 -
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1-num2}'
# 乘 *
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1*num2}'
# 除 /
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1/num2}'
// %0.2f 保留两位小数
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;printf "%0.2f\n",num1/num2}'
# 模 %
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print num1%num2}'
# 乘方 ^ 或 **
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=30;print "%0.2f\n",num1**num2}'
# ++x
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=++num1;print num1,num2}'
# x++
[root@VM_0_14_centos /]# awk 'BEGIN{num1=20;num2=num1++;print num1,num2}'
如:统计 test.txt 文件中的空白行数量
[root@VM_0_14_centos /]# awk '/^$/{total++}END{print total}' /test.txt
3. awk动作中的条件及循环:
如:判断 test.txt 文件中第三列数字大于50且小于100的行
[root@VM_0_14_centos /]# awk 'BEGIN{FS=":"}{if($3>50 && $3<100) print $0}' /test.txt
awk中的字符串函数:
函数名 | 解释 | 函数返回值 |
---|---|---|
length(str) | 计算字符串长度 | 整数长度值 |
index(str1,str2) | 在str1中查找str2的位置 | 返回值为位置索引,从1计数 |
tolower(str) | 转换为小写 | 转换后的小写字符串 |
toupper(str) | 转换为大写 | 转换后的大写字符串 |
substr(str,m,n) | 从str的m个字符开始,截取n位 | 截取后的子串 |
split(str,arr,fs) | 按fs切割字符串,结果保存arr | 切割后的子串的个数 |
match(str,RE) | 在str中按照RE查找,返回位置 | 返回索引位置 |
sub(RE,RepStr,str) | 在str中搜索符合RE的字串,将其替换为RepStr,只替换第一个 | 替换的个数 |
gsub(RE,RepStr,str) | 在str中搜索符合RE的字串,将其替换为RepStr,替换所有 | 替换的个数 |
注:awk中的下标是从 1 开始,shell中下标是从 0 开始
如:1.以 : 为分隔符,返回 /etc/passwd 中的每行中每个字段的长度:
新建文件 test.awk(后缀是.awk)
,新手不熟悉先这样新建文件写,内容如下
BEGIN {
FS=":"
}
{
i=1
while(i <= NF){ # NF 当前行的字段个数,也就是有多少列
if(i == NF)
printf "%d",length($i)
else
printf "%d:",length($i)
}
print "" # print 输出默认就是空格换行
}
执行的时候,输入命令 awk -f test.awk /etc/passwd
,-f
是指引入文件
网友评论