匹配的两种用法
RegExp
- 匹配 /etc/passwd 文件行中含有 root 字符串的所有行
> awk '/root/{print $0}' passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin
- 匹配 /etc/passwd 文件行中以 yarn 开头的所有行
> awk '/^yarn/{print $0}' passwd
运算符匹配
关系运算符 | 含义 |
< | 小于 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
== | 等于 |
!= | 不等于 |
~ | 匹配正则表达式 |
!~ | 不匹配正则表达式 |
- 以:为分隔符,匹配 /etc/passwd 文件中第 3 个字段小于 50 的所有行信息
> awk 'BEGIN{FS=":"}$3<50{print $0}' passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nscd:x:28:28:NSCD Daemon:/:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
- 以:为分隔符,匹配 /etc/passwd 文件中第 7 个字段不为 /bin/bash 的所有行信息
> awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nolog ...
布尔运算符匹配
布尔运算符 | 含义 |
|| | 或 |
&& | 与 |
! | 非 |
- 以:为分隔符,匹配 /etc/passwd 文件中包含 hdfs 或 yarn 的所有行信息
> awk 'BEGIN{FS=":"} hdfs|| yarn {print $0}' passwd
- 以:为分隔符,匹配 /etc/passwd 文件中第 3 个字段小于 50 并且第 4 个字段大于 50 的所行信息
> awk 'BEGIN{FS=":"}$3<50 && $4>50{print $0}' passwd games:x:12:100:games:/usr/games:/sbin/nologin
动作中的表达式用法
运算符 | 含义 |
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 模 |
^或** | 乘方 |
++x | 在返回 x 变量之前,x 变量加1 |
x++ | 在返回 x 变量之后,x 变量加1 |
- 使用 awk 计算 /etc/services 中的空白行数量
> awk 'BEGIN{count=0}/^$/{count++;}END{print count}' services 20
- 计算学生课程分数平均值,学生课程文件内容如下:
> cat student.txt allen 80 90 87 91 mike 78 86 93 96 Kobe 66 92 82 78 Jerry 98 74 66 54 wang 87 21 100 43 > awk 'BEGIN{printf "%-10s %-10s %-10s %-10s %-10s %-10s \n","name","chinese","math","english","computer","avg"}{avg=($2+$3+$4+$5)/4;printf "%-10s %-10d %-10d %-10d %-10d %-10d \n",$1,$2,$3,$4,$5,avg}' student.txt name chinese math english computer avg allen 80 90 87 91 87 mike 78 86 93 96 88 Kobe 66 92 82 78 79 Jerry 98 74 66 54 73 wang 87 21 100 43 62
动作中的条件及循环语句
条件语句
if (condition) action-1 else action-2
- 以:为分隔符,只打印 /etc/passwd 中第 3 个字段的数值在 50-100 范围内的行信息
> awk 'BEGIN{FS=":"}$3>50 && $3<100{print $0}' passwd dbus:x:81:81:System message bus:/:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin
- 计算下列每个同学的平均分数,并且只打印平均分数大于90的同学姓名和分数信息
> cat student.txt allen 80 90 87 91 mike 78 86 93 96 Kobe 66 92 82 78 Jerry 98 74 66 54 wang 87 21 100 43 > awk 'BEGIN{printf "%-10s %-10s %-10s %-10s %-10s %-10s \n","name","chinese","math","english","computer","avg"}{avg=($2+$3+$4+$5)/4;if(avg>90)printf "%-10s %-10d %-10d %-10d %-10d %-10d \n",$1,$2,$3,$4,$5,avg}' student.txt
循环语句
for (initialisation; condition; increment/decrement) action while (condition) action do( )while()
- 计算1+2+3+4+…+100的和,请使用while、 do while、 for三种循环方式实现(我只写for了)
> awk 'BEGIN{sum=0;for(i=0;i<=100;i++)sum+=i;print sum}' 5050
字符串函数
函数名 | 解释 | 函数返回值 |
length(str) | 计算字符串长度 | 整数长度值 |
index(str1,str2) | 在 str1 中查找 str2 的位置 | 返回值为位置索引,从 1 计数 |
tolower(str) | 转换为小写 | 转换后的小写字符串 |
toupper(str) | 转换为大写 | 转换后的大写字符串 |
substr(str,m,n) | 从 str 的 m 个字符开始,截取 n 位 | 截取后的子串 |
split(str,array,fs) | 按 fs 切割字符串,结果保存 array | 切割后的子串的个数 |
match(str,RE) | 在 str 中按照 RE 查找,返回位置 | 返回索引位置 |
sub(RE,RepStr,str) | 在 str 中搜索符合 RE 的字串,将其替换为 RepStr;(只替换第一个) | 替换的个数 |
gsub(RE,RepStr,str) | 在 str 中搜索符合 RE 的字串,将其替换为 RepStr;(替换所有) | 替换的个数 |
- 以:为分隔符,返回 /etc/passwd 中每行中每个字段的长度
> awk '{print length($0)}' passwd 31 32 39 36 40 31 44 32 46 44 ...
- 搜索字符串“I have a dream“中出现“ea“字符串的位置
> awk 'BEGIN{str="I have a dream";print index(str,"ea")}' 12
- 将字符串“Hadoop is a bigdata Framawork“全部转换为小写
> awk 'BEGIN{str="Hadoop is a bigdata Framawork";print tolower(str)}' hadoop is a bigdata framawork
- 将字符串“Hadoop is a biadata Framawork“全部转换为大写
> awk 'BEGIN{str="Hadoop is a bigdata Framawork";print toupper(str)}' HADOOP IS A BIGDATA FRAMAWORK
常用选项
选项 | 解释 |
-v | 参数传递 |
-f | 指定脚本文件 |
-F | 指定分割符(FS) |
-V | 查看 awk 的版本号 |
… | … |
数组用法
shell 中数组的用法:
array=("百度" "阿里" "腾讯")
功能 | 命令 |
打印元素 | echo ${array[2]} |
打印元素个数 | echo ${#array[@]} |
打印元素长度 | echo ${#array[3]} |
给元素赋值 | array[1]=”字节跳动” |
删除元素 | unset array[2];unset array; |
分片访问 | echo ${array[@]: 1:3} |
元素内容替换 | $array [@/e/E] |
数组的遍历 | for a in ${array[0]} do echo $a done |
awk 中数组的用法:
array[index]=value
功能 | 命令 |
创建数组 | array[1]=”hello” |
删除数组元素 | delete array[1] |
多维数组 | array[“0,0”] = 100; array[“0,1”] = 200; array[“0,2”] = 300; array[“1,0”] = 400; array[“1,1”] = 500; array[“1,2”] = 600; |
- 统计主机上所有的 TCP 连接状态数,按照每个 TCP 状态分类
> netstat -an | grep tcp| awk '{array[$6]++}END{ for (a in array) print a,array[a]}' LISTEN 21 SYN_RECV 1 ESTABLISHED 4 TIME_WAIT 2
- 计算横向数据综合,计算纵向数据总和
> cat student.txt allen 80 90 87 91 mike 78 86 93 96 Kobe 66 92 82 78 Jerry 98 74 66 54 wang 87 21 100 43 > awk 'BEGIN{printf "%-10s %-10s %-10s %-10s %-10s %-10s \n","name","chinese","math","english","computer","total"}{total=$2+$3+$4+$5;totol_count+=total;chinese_count+=$2;math_count+=$3;english_count+=$4;computer_count+=$5;printf "%-10s %-10d %-10d %-10d %-10d %-10d \n",$1,$2,$3,$4,$5,total}END{printf "%-10s %-10d %-10d %-10d %-10d %-10d \n","total",chinese_count,math_count,english_count,computer_count,totol_count}' student.txt name chinese math english computer total allen 80 90 87 91 348 mike 78 86 93 96 353 Kobe 66 92 82 78 318 Jerry 98 74 66 54 292 wang 87 21 100 43 251 total 409 363 428 362 1562