awk是一个文本处理工具,通常用于处理数据并生成结果报告
awk语法
语法格式
- awk ‘BEGIN{}PATTERN{commands}END{}’ file_name
- stand out |awk ‘BEGIN{}PATTERN{commands}END{}’
- BEGIN{} 正式处理数据之前执行
- pattern 匹配模式
- {commands} 处理命令,可能多行
- END{} 处理完所有匹配数据后执行
awk内置变量
内置变量 | 含义 |
---|---|
$0 | 整行内容 |
$1-$n | 当前行的第1-n个字段 |
NF | 当前行的字段个数,也就是有多少列 |
NR | 当前的行的行号,从1开始计数 |
FNR | 多文件处理时,每个文件行号单独计算,都是从0开始 |
FS | 输入字段分隔符。不指定默认是空格或者tab键分割 |
RS | 输入行分隔符。默认回车换行 |
OFS | 输出字段分隔符。默认为空格 |
ORS | 输出行分隔符。默认为回车换行 |
FILENAME | 当前输入的文件名称 |
ARGC | 当前命令行参数个数 |
ARGV | 当前命令行参数数组 |
1awk '{print $0}' awk.txt. #打印全部行
2awk 'BEGIN{FS=";"}{print $1}' awk.txt # 分隔符为; 打印第一个字段,如果一行里没有;那么这行都为$1
3awk '{print NF}' awk.txt #每一行字段数
4awk '{print NR}' awk1.txt awk2.txt # 打印行号 累计计数 awk1.txt如果有2行那么awk2.txt是从行号3开始的
5awk '{print FNR}' awk1.txt awk2.txt # 打印行号 ,每个文件单独计数
1cat awk.txt
2#Hadoop|Spack|Flume--GO|JAVA|C++--|PHP|PYTHON|JAVASCRIPT
3
4awk 'BEGIN{RS="--"}{print $0}' awk.txt
5#Hadoop|Spack|Flume
6#GO|JAVA|C++
7#|PHP|PYTHON|JAVASCRIPT
8
9awk 'BEGIN{RS="--";FS="|"}{print $3}' awk.txt
10#Flume
11#C++
12#PYTHON
13
14awk 'BEGIN{RS="--";FS="|";ORS="&";OFS=":"}{print $1,$3}' awk.txt
15#Hadoop:Flume&GO:C++&:PYTHON&
16
17
18awk '{print FILENAME}' awk.txt #有几行打印几次 awk.txt
19awk '{print ARGC}' awk.txt # 2个参数 一个是awk命令 一个awk.txt
20awk '{print ARGC}' awk.txt awk.txt #3个
21awk 'BEGIN{FS=":"}{print $NF}' /etc/passwd #与下面等价 NF=7 打印最后一列
22awk 'BEGIN{FS=":"}{print $7}' /etc/passwd
常用选项
选项 | 含义 |
---|---|
-v | 定义变量或引用变量 |
-f | 指定awk 命令文件 |
-F | 指定分隔符 |
-V | 查看awk的版本号 |
格式化输出printf
格式符 | 含义 |
---|---|
%s | 打印字符串 |
%d | 打印十进制数 |
%f | 打印浮点数 |
%x | 打印十六进制数 |
%o | 打印八进制数 |
%e | 打印数字的科学计数法形式 |
%c | 打印单个自负的ASCII码 |
修饰符 | 含义 |
---|---|
- | 左对齐 |
+ | 右对齐 |
# | 8进制在前面加0,显示16进制在前面加0x |
- 以字符串格式打印/etc/passwd的第7个字段,以":“作为分隔符
1 awk 'BEGIN{FS=":"} {printf "%s\n",$7}' /etc/passwd
- 以10进制格式打印/etc/passwd的第三个字段,以”:“作为分隔符
1 awk 'BEGIN{FS=":"} {printf "%d\n",$3}' /etc/passwd
- 以浮点数格式打印/etc/passwd的第三个字段,以”:“作为分隔符
1 awk 'BEGIN{FS=":"} {printf "%.2f\n",$3}' /etc/passwd
模式匹配
2种匹配模式
- 正则匹配
- 运算符匹配
正则匹配
匹配/etc/passwd中含有root的所有行
1awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd
匹配/etc/passwd 以jenkins开始的所有行
1awk 'BEGIN{FS=":"}/jenkins/{print $0}' /etc/passwd
运算符匹配
关系运算符匹配
- < 小于
>
大于>=
大于等于- <= 小于等于
- ~ 正则匹配
- !~ 正则不匹配
- == 等于
- != 不等于
布尔运算符匹配
- || 或
- && 与
- ! 非
以:分隔符,匹配/etc/passwd文件中第三个字段小于50的所有行信息
1awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd
以:分隔符,匹配/etc/passwd文件中shell是/bin/bash的所有行
1awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd
以:分隔符,匹配/etc/passwd 用户id 是3位数字以上的 行
1awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/passwd
匹配/etc/passwd 用户名是vagrant或是root
1awk 'BEGIN{FS=":"}$1=="root" || $1=="vagrant"{print $0}' /etc/passwd
表达式
运算符 | 含义 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
++x | 在变量返回之前, x+1 |
x++ | 在变量返回之后, x+1 |
** 或者 ^ | 乘方 |
% | 取模 |
1awk 'BEGIN{num1=20;num2=num1+30;print num1,num2}'
2#20 50
3awk 'BEGIN{num1=20;num2=num1+30;print num1+num2}' # 70
4awk 'BEGIN{num1=20;num2=num1+30;print num1-num2}' # -30
5awk 'BEGIN{num1=20;num2=num1+30;print num1*num2}' #1000
6awk 'BEGIN{num1=20;num2=num1+30;print num1**2}' # 400
7awk 'BEGIN{num1=20;num2=num1+30;printf "%.2f",num1**2}' # 400.00
计算空白行
1 awk '/^$/{sum++}END{print sum}' xx.sql
1root@k8smaster:/home/maozhongyu1# cat xx.sql
2mao 50 10 40
3zhang 30 20 10
4li 10 20 40
5
6
7root@k8smaster:/home/maozhongyu1# awk 'BEGIN{printf "%-8s%-8s%-8s%-8s%s","name","yuwen","shuxue","yingyu","平均分\n";}{total=$2+$3+$4;avg=total/3; printf "%-8s%-8d%-8d%-8d%.2f\n",$1,$2,$3,$4,avg; }' xx.sql
8name yuwen shuxue yingyu 平均分
9mao 50 10 40 33.33
10zhang 30 20 10 20.00
11li 10 20 40 23.33
动作中的条件
1root@k8smaster:/home/maozhongyu1# awk 'BEGIN{FS=":"} {if($3>1000) print $1}' /etc/passwd
2nobody
3maozhongyu
4maozhongyu1
5root@k8smaster:/home/maozhongyu1# awk 'BEGIN{FS=":"} {if($3>1000){print $1}}' /etc/passwd
6nobody
7maozhongyu
8maozhongyu1
1root@k8smaster:/home/maozhongyu1# cat xx.sql
2mao 50 10 40
3zhang 30 20 10
4li 10 20 40
5root@k8smaster:/home/maozhongyu1# awk '{if($2>20) { print $1 }}' xx.sql
6mao
7zhang
8
9
10root@k8smaster:/home/maozhongyu1# awk '{if($2>40){printf "%s%s\n","大于40的用户",$1} else if($2<=40 && $2 >=25) {printf "%s%s\n","中规中矩",$1 }else {printf "%s%s\n","有点垃圾",$1}}' xx.sql
11大于40的用户mao
12中规中矩zhang
13有点垃圾li
动作中的循环
do while
1[vagrant@maozhongyu ~]$awk 'BEGIN{ total=0;i=1;do {total +=i;i++;} while(i<=100);print total}'
25050
while
1[vagrant@maozhongyu ~]$awk -v i=1 -v sum=0 'BEGIN{while(i<=100){sum+=i;i++};print sum}'
25050
for
1awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}'
字符串函数
函数名 | 解释 | 函数返回值 |
---|---|---|
length(str) | 计算字符串长度 | 整数长度值 |
index(str1,str2) | 在str1中查找str2的位置 | 返回值为位置索引,从1计数 |
tolower(str) | 转换为小写 | 转换后的小写字符串 |
topper(str) | 转换为大写 | 转换后的大写字符串 |
substr(str,m,n) | 从str的m个字符串开始,截取n位 | 截取后的字符串 |
split(str,arr,fs) | 按fs切割字符串, 结果保存arr | 切割后的子串的个数 |
match(str,RE) | 在str中按照RE查找,返回位置 | 返回索引位置 |
sub(RE,replace,str) | 在str中查找符合RE,替换为replace 只替换一个 | 替换的个数 |
gsub(RE,replace,str) | 在str中查找符合RE,替换为replace 。替换全部 | 替换的个数 |
用户名长度
1$awk 'BEGIN{FS=":"} { printf "%d\n",length($1);}' /etc/passwd