awk 操作符
算术操作符: x+y, x-y, x*y, x/y, x^y, x%y -x: 转换为负数 +x: 转换为数值
字符串操作符: 没有符号的操作符, 字符串连接
赋值操作符: =, +=, -=, *=, /=, %=, ^= ++, --
比较操作符: ==, !=,>,>=, <, <=
awk -F: '!($3==0) {print $1}' /etc/passwd
模式匹配符: ~ 左边是否和右边匹配包含 !~ 是否不匹配
- awk -F: '$0 ~ /root/{print $1}' /etc/passwd
- awk -F: '$3==0' /etc/passwd
awk 正则匹配表达式
(1) 如果未指定: 空模式, 匹配每一行
(2) /regular expression/: 仅处理能够模式匹配到的行, 需要用 / / 括起来
awk '/^UUID/{print $1}' /etc/fstab
(3) relational expression: 关系表达式, 结果为 "真" 才会被处理
awk '!0' /etc/passwd
(4) line ranges: 行范围
startline,endline:/pat1/,/pat2/ 不支持直接给出数字格式
awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd
(5) BEGIN/END 模式
BEGIN{}: 仅在开始处理文件中的文本之前执行一次 END{}: 仅在文本处理完成之后执行一次
awk 控制语句
if-else while 循环 do-while 循环 for 循环 switch 语句 break 和 continue
next: 提前结束对本行处理而直接进入下一行处理 (awk 自身循环)
awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
awk 自带对文件行内容的循环, awk 使用循环一般是对切割数据列进行循环操作
awk 的基本格式 awk -F: '{}' filepath
性能比较
- time (awk 'BEGIN{ total=0;for(i=0;i<=10000;i++){total+=i;};print total;}')
- time(total=0;for i in {1..10000};do total=$(($total+i));done;echo $total)
- time(for ((i=0;i<=10000;i++));do let total+=i;done;echo $total)
- time(seq -s "+" 10000|bc)
awk 数组
默认是关联数组
若要遍历数组中的每个元素, 要使用 for 循环
for(var in array) {for-body} 注意: var 会遍历 array 的每个索引
awk 函数
数值处理:
rand(): 返回 0 和 1 之间一个随机数 awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'
字符串处理:
echo $a | awk -F ""'{for(i=1;i<=NF;i++){if($i ~ /^[0-9]+$/) printf"%s", $i}}'
length([s]): 返回指定字符串的长度
sub(r,s,[t]): 对 t 字符串进行搜索 r 表示的模式匹配的内容, 并将第一个匹配的内容替换为 s
echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
gsub(r,s,[t]): 对 t 字符串进行搜索 r 表示的模式匹配的内容, 并全部替换为 s 所表示的内容
echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
split(s,array,[r]) 以 r 为分隔符, 切割字符串 s, 并将切割后的结果保存至 array 所表示的数组中, 第一个索引值为 1, 第二个索引值为 2
netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++} END{for (i in count) {print i,count[i]}}'
自定义函数
awk 中调用 shell 命令
system 命令
空格是 awk 中的字符串连接符, 如果 system 中需要使用 awk 中的变量可以使用 空格分隔, 或者说除了 awk 的变量外其他一律用 "" 引用起来.
- awk BEGIN'{system("hostname") }' awk BEGIN'{system("ifconfig") }'
- awk 'BEGIN{score=100; system("echo your score is "score) }'
awk 传递值给 shell 循环, shell 命令不能直接在 awk 的 action 中执行
- #!/bin/bash
- awk '/^[0-9]/{ip[$1]++}END{for(i in ip){if(ip[i]>30) print i}}' access_log | while read ip; do
- echo $ip
- done
- View Code
awk 脚本
将 awk 程序写成脚本, 直接调用或执行
向 awk 脚本传递参数
格式: awkfile var=value var2=value2... Inputfile
注意: 在 BEGIN 过程中不可用. 直到首行输入完成以后, 变量才可用. 可以通 过 - v 参数, 让 awk 在执行 BEGIN 之前得到变量的值.
命令行中每一个指定的变 量都需要一个 - v 参数
awk 实例
- awk '{for(i=1;i<=NF;i++){word[$i]++}}END{for(j in word){print j,word[j]}}' /etc/rc.sysinit
- [root@centos7 ~]# awk '{if($NF=="m"){sum_m+=$2;num_m++} else{sum_f+=$2;num_f++}}END{printf"male:%.2f\nfemale:%.2f\n",sum_m/num_m,sum_f/num_f}' score
- male:99.50
- female:95.00
- [root@centos7 ~]# awk '{pcount[$3]++;s[$3]+=$2}END{for(i in pcount){print i, pcount[i],s[i]/pcount[i]}}' score
- m 2 99.5
- f 2 95
- [root@centos7 ~]# echo "2008:08:08 :08" | awk 'sub(/:/,"-",$1)'
- 2008-08:08 :08
- [root@centos7 ~]# echo "2008:08:08 :08" | awk 'gsub(/:/,"-",$1)'
- 2008-08-08 :08
- [root@centos7 ~]# echo "2008:08:08:08" | awk 'gsub(/:/,"-",$1)'
- 2008-08-08-08
- [root@centos7 ~]# head -n1 /etc/passwd | awk '{split($0,arr,":")}END{for(i in arr){print i,arr[i]}}'
- 4 0
- 5 root
- 6 /root
- 7 /bin/bash
- 1 root
- 2 x
- 3 0
- [root@centos7 ~]# netstat -an |awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'
- 192.168.33.1 2
- 0.0.0.0 5
- View Code
- awk -F: -v i=0 'i{print $0}' /etc/fstab
- [root@centos7 ~]# awk '/^[^#]/' /etc/fstab
- UUID=1ec9c7b3-bec1-4998-9aad-057423419431 / xfs defaults 0 0
UUID=df74adc0-09cd-4a97-a1e4-9f0d4a4b5796 /boot xfs defaults 0 0
UUID=bacf4f88-3be9-4e74-ba5b-90274a2099ab /data xfs defaults 0 0
- UUID=339ab167-206a-4210-a36d-8d575579959e swap swap defaults 0 0
- [root@centos7 ~]# awk '/^ *#/' /etc/fstab
- #
- # /etc/fstab
- # Created by anaconda on Wed Mar 28 01:53:52 2018
- #
- [root@centos7 ~]# awk -F: '/\/bin\/bash$/{print $1,$NF}' /etc/passwd
- root /bin/bash
- yanxianghui /bin/bash
- tomcat /bin/bash
- [root@centos7 ~]# awk -F: '/^root\>/,/^mail\>/{print $1}' /etc/passwd
- root
- [root@centos7 ~]# df -h | awk -F% '$0 ~ /^\/dev\/sd/{print $1}'| awk '$5>=10'
- /dev/sda1 1014M 194M 821M 20
- [root@centos7 ~]# df -h | awk -F% '$0 ~ /^\/dev\/sd/{print $1}'
- /dev/sda2 50G 4.2G 46G 9
- /dev/sda3 30G 82M 30G 1
- /dev/sda1 1014M 194M 821M 20
- View Code
- [root@centos7 ~]# awk '/^[0-9]/{ip[$1]++}END{for (i in ip){print i,ip[i]}}' access_log
- 172.20.101.111 2
- 172.20.101.238 19
- 172.20.101.188 6
- View Code
来源: http://www.bubuko.com/infodetail-2607433.html