内容简介:AWK是一种处理文本文件的语言,是一个强大的文本分析工具。
简述awk命令及用法
AWK是一种处理文本文件的语言,是一个强大的文本分析工具。
语法
awk [options]'program' {filenames}
参数
-F:指明输入时用到的字段分隔符,默认是空格符 -v var=value: 自定义变量
program
program: PATTERN{ACTION STATEMENTS} 语句之间用分号分隔
- print
- 格式 :print item1,item2,….
$0:表示整个当前行 $1:每行第一个字段 NR:number of record, 总行数; NF:number of field,字段数量 {print NF}:打印每行的字段 {print $NF}:打印第NF个字段值(最后一个字段的值) FNR:单个数据文件处理的行数 \t:制表符 \n:换行符
- 实例
- F & $0
#输出整行,awk {print} /etc/passwd = awk '{print $0}' /etc/passwd ~]# awk {print} /etc/passwd ~]# awk '{print $0}' /etc/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 #":"为分格符输出第一个字符 ~]# awk -F":" '{print $1}' /etc/passwd root bin daemon #$1与$3相连输出,不分隔 ~]# awk -F":" '{print $1 $3}' /etc/passwd root0 bin1 daemon2 #多了一个逗号,$1与$3使用空白分格分隔 ~]# awk -F":" '{print $1,$3}' /etc/passwd root 0 bin 1 daemon 2 #$1与$3使用分格符分隔,自定义分隔符 ~]# awk -F":" '{print $1 "," $3}' /etc/passwd root,0 bin,1 daemon,2 ~]# awk -F":" '{print $1 "-" $3}' /etc/passwd root-0 bin-1 daemon-2 #自定义输出内容 ~]# awk -F":" '{print "Username:" $1" \t Uid:" $3 }' /etc/passwd Username:root Uid:0 Username:bin Uid:1
- NF
#显示每行有多少字段 ~]# awk -F: '{print NF}' /etc/passwd 7 7 7 #将每行第NF个字段的值打印出来 ~]# awk -F: '{print $NF}' /etc/passwd /bin/bash /sbin/nologin /sbin/nologin #只输出字段数=7的行 ~]# awk -F":" 'NF==7 {print }' /etc/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 #输出字段数>2的行 ~]# awk -F":" 'NF>2{print $0}' /etc/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
- NR
#输出每行的行号 localhost ~]# awk '{print NR,$0}' /etc/passwd 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin #显示第5行 localhost ~]# awk -F: 'NR==5{print}' /etc/passwd lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin #显示5行以后的数据,并在前面显示行号 localhost ~]# awk -F: 'NR>5{print NR ,$0}' /etc/passwd 6 sync:x:5:0:sync:/sbin:/bin/sync 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 halt:x:7:0:halt:/sbin:/sbin/halt ..... #显示5行和第8行,并在前面显示行号 localhost ~]#awk -F: 'NR==5 || NR == 8 {print NR ,$0}' /etc/passwd 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 8 halt:x:7:0:halt:/sbin:/sbin/halt
- FNR&NR
localhost tmp]# cat data3 hello hello hello localhost tmp]# awk '{print $0 ,"\t""FNR="FNR,"NR="NR}' data3 data3 hello FNR=1 NR=1 hello FNR=2 NR=2 hello FNR=3 NR=3 hello FNR=1 NR=4 hello FNR=2 NR=5 hello FNR=3 NR=6
- F & $0
- 格式 :print item1,item2,….
- 格式化打印printf
printf FORMAT, item1, item2, ... (1) FORMAT必须给出; (2) 不会自动换行,需要显式给出换行控制符,\n (3) FORMAT中需要分别为后面的每个item指定一个格式化符号;
- 格式符:
%c: 显示字符的ASCII码; %d, %i: 显示十进制整数; %e, %E: 科学计数法数值显示; %f:显示为浮点数; %g, %G:以科学计数法或浮点形式显示数值; %s:显示字符串; %u:无符号整数; %%: 显示%自身;
- 修饰符
#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度; -: 左对齐 +:显示数值的符号
- 说明
(1). 可以在"%"和字母之间插进数字表示最大场宽。 例如:%3d 表示输出3位整型数, 不够3位右对齐。 %9.2f 表示输出场宽为9的浮点数, 其中小数位为2, 整数位为6,小数点占一位, 不够9位右对齐。 %8s 表示输出8个字符的字符串, 不够8个字符右对齐。 如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出.但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按实际整数位输出;若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出. 另外, 若想在输出值前加一些0, 就应在场宽项前加个0。 例如: %04d 表示在输出一个小于4位的数值时, 将在前面补0使其总宽度为4位。 如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。 例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。 (2). 可以在"%"和字母之间加小写字母l, 表示输出的是长型数。 例如: %ld 表示输出long整数 %lf 表示输出double浮点数 (3). 可以控制输出左对齐或右对齐, 即在"%"和字母之间加入一个"-" 号可说明输出为左对齐, 否则为右对齐。 例如: %-7d 表示输出7位整数左对齐 %-10s 表示输出10个字符左对齐
- 实例
#%d 显示十进制整数 ~]# echo "1.7 2.52" | awk '{printf ("%d\n",$2)}' 2 #%f 显示浮点数 ~]# echo "1.7 2.52" | awk '{printf ("%f\n",$1)}' 1.700000 #四舍五入输入整数 ~]# echo "1.5" | awk '{printf ("%.f\n",$1)}' 2 echo "1.4" | awk '{printf ("%.f\n",$1)}' 1 #以3位长度、1位小数,"."占一位,浮点换行输出第2个域(四舍五入) ~]# echo "1.7 2.52" | awk '{printf ("%3.1f\n",$2)}' 2.5 #以6位长度,其中整数占2位,不足2位空格补足,“.”占一位,小数占3位,不足3位用0补足 ~]# echo "1.7 2.52" | awk '{printf ("%6.3f\n",$2)}' 2.520 #指数形式的浮点数输出 ~]# echo "1.7 2.52" | awk '{printf ("%e\n",$1)}' 1.700000e+00 #用0补充格式 ~]# echo "123 1" | awk '{printf("%d\t%03d\n",$1,$2)}' 123 001
- 格式符:
- BEGIN/END模式
BEGIN{}: 仅在开始处理文件中的文本之前执行一次; END{}:仅在文本处理完成之后执行一次;
- 实例
#开头显示“The data of passwd” localhost ~]# awk 'BEGIN{print "The data of passwd"} {print}' /etc/passwd The data of 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 #显示第一行,并在开头和末尾显示“The data of passwd” localhost ~]# awk 'BEGIN{print "print /etc/passwd"} NR==1{print} END{print "print /etc/passwd"}' /etc/passwd print /etc/passwd root:x:0:0:root:/root:/bin/bash print /etc/passwd
- 实例
- 使用变量
- 内建变量:字段和记录分隔符变量
FS:input field seperator,输入字段分隔符,默认为空白字符 OFS:output field seperator,输出字段分隔符, 默认空白字符; RS:input record seperator,输入时的换行符; ORS:output record seperator,输出时的换行符; FIELDWIDTHS:指定列
- 实例
- FS&OFS
#自定义分输入隔符为“:” localhost ~]#awk 'BEGIN{FS=":"} NR<4{print $1,$2,$3}' /etc/passwd root x 0 bin x 1 daemon x 2 #自定义分输入隔符为“:”,输出分隔符为“-” localhost ~]# awk 'BEGIN{FS=":" ;OFS="-"} NR<4{print $1,$2,$3}' /etc/passwd root-x-0 bin-x-1 daemon-x-2
- RS&ORS
#输入时以回车符为分隔符,空白行为换行符, localhost tmp]# cat data2 Riley Mullen 123 Main Street Chicago, IL 60601 (312)555-1234 Frank Williams 456 Oak Street Indianapolis, IN 46201 (317)555-9876 Haley Snell 4231 Elm Street Detroit, MI (313)555-4938 localhost tmp]# awk 'BEGIN{FS="\n"; RS=""}{print $1 ,$4}' data2 Riley Mullen (312)555-1234 Frank Williams (317)555-9876 Haley Snell (313)555-4938
- FIELDWIDTHS
#以特定列为分隔 localhost tmp]# cat data1 1005.3247596.37 115-2.349194.00 05810.1298100.1 localhost tmp]# awk 'BEGIN{FIELDWIDTHS="3 5 2 5"} {print $1,$2,$3,$4}' data1 100 5.324 75 96.37 115 -2.34 91 94.00 058 10.12 98 100.1
- 自定义变量
- 在脚本中给变量复制
变量名可以是任意数目的字母、数字和下划线,但不能以数字开头
- 实例
localhost ~]#awk 'BEGIN{test="hello everyone";print test}' hello everyone localhost ~]# awk 'BEGIN{x=4;x=x*2+3;print x}' 11
- 实例
- 在命令行上给变量复制
localhost tmp]# cat data4 data11 data12 data13 data21 data22 data23 data31 data32 data33 localhost tmp]# cat script1 BEGIN{print "The starting value is",n}{print $n} localhost tmp]# awk -v n=3 -f script1 data4 The starting value is 3 data13 data23 data33
- 在脚本中给变量复制
- 内建变量:字段和记录分隔符变量
- 数组变量
var[index] = element var:变量名 index:索引值 element:数据元素值
-
遍历数组变量
for (var in array) { statements }
for语句在每次循环时将关联数组array下一个索引值赋给变量var,然后执行一遍statements
- 实例
localhost ~]# awk 'BEGIN{var["a"] =1;var["b"]=2;var["c"]=3;var["d"]=4;for (i in var) {print var[i]}}' 1 2 3 4 #统计IP链接数 localhost ~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log 192.168.1.48 10 #统计tcp链接状态和数量,IPV4 localhost ~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}' LISTEN 2 ESTABLISHED 3 #统计/etc/fstab文件中每个文件系统类型出现的次数 localhost ~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab xfs 1 #统计指定文件中每个单词出现的次数; localhost ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
- 实例
-
- 字符串匹配
// 纯字符匹配 !// 纯字符不匹配 ~// 字段值匹配 !~// 字段值不匹配 ~/a1|a2/ 字段值匹配a1或a2
- 实例
#显示 mysql 相关信息 localhost ~]# awk '/mysql/{print $0}' /etc/passwd mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin #显示非mysql localhost ~]# awk '!/mysql/{print $0}' /etc/passwd #显示mail和mysql localhost ~]# awk '/mail|mysql/{print $0}' /etc/passwd mail:x:8:12:mail:/var/spool/mail:/sbin/nologin mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin #显示$1匹配mail localhost ~]# awk -F: '$1~/mail/{print $1}' /etc/passwd mail
- 实例
- 操作符
- 算数操作符
x+y: 加 x-y:减 x*y:乘 x/y:除 x^y:次方 x%y:余数
- 赋值操作符
= : x=y +=: x+=5 (x=x+5) -=: x-=5 (x=x-5) /=: x/=5 (x=x/5) %=: x%=5 (x=x%5) ^=: x^=5 (x=x^5) ++: x++ (x=x+1) --: x-- (x=x-1)
- 比较操作符
> >= < <= != ==
- 模式匹配符
~:是否匹配 !~:是否不匹配
- 逻辑操作符:
&& || !
- 条件表达式
selector?if-true-expression:if-false-expression 实例: ~]# awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd root:Sysadmin or SysUser bin:Sysadmin or SysUser daemon:Sysadmin or SysUser adm:Sysadmin or SysUser lp:Sysadmin or SysUser sync:Sysadmin or SysUser
- 算数操作符
- 控制语句
-
if语句
if(condition) {statments} if(condition) {statments} else {statements}
实例:
#简单的if语句 ~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd root centos test linux testuser #if-else语句 ~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd ~]#awk -F: '{if($3>=1000) printf "Common user: %s\n",$1; else printf "root or Sysuser: %s\n",$1}' /etc/passwd root or Sysuser: root root or Sysuser: bin root or Sysuser: daemon root or Sysuser: adm root or Sysuser: lp #在if中执行多条语句和if-else语句 [root@localhost tmp]# cat data1 10 5 13 50 34 [root@localhost tmp]# awk '{if ($1>20) {x= $1*2; print $1,x}}' data1 50 100 34 68 ~]# awk '{if($1>20) print $1*2;else print $1/2}' data1 5 2.5 6.5 100 68 #打印磁盘使用率超过10%的 ~]# df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=10) print $1}' /dev/mapper/cl-root /dev/sda1
-
while循环
while(conditon) {statments} 条件“真”,进入循环;条件“假”,退出循环
实例:对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用
~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg linux16 7 /vmlinuz-3.10.0-514.el7.x86_64 30 root=/dev/mapper/cl-root 24 ro 2 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 rhgb 4 quiet 5 LANG=en_US.UTF-8 16 linux16 7 /vmlinuz-0-rescue-071d709683fd4359a4845645d1906b29 50 root=/dev/mapper/cl-root 24 ro 2 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 rhgb 4 quiet 5 ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /etc/grub2.cfg linux16 7 /vmlinuz-3.10.0-514.el7.x86_64 30 root=/dev/mapper/cl-root 24 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 LANG=en_US.UTF-8 16 linux16 7 /vmlinuz-0-rescue-071d709683fd4359a4845645d1906b29 50 root=/dev/mapper/cl-root 24 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17
- do-while循环
至少执行一次循环体
-
for循环
for(expr1;expr2;expr3) {statements}
实例
~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg linux16 7 /vmlinuz-3.10.0-514.el7.x86_64 30 root=/dev/mapper/cl-root 24 ro 2 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 rhgb 4 quiet 5 LANG=en_US.UTF-8 16 linux16 7 /vmlinuz-0-rescue-071d709683fd4359a4845645d1906b29 50 root=/dev/mapper/cl-root 24 ro 2 crashkernel=auto 16 rd.lvm.lv=cl/root 17 rd.lvm.lv=cl/swap 17 rhgb 4 quiet 5
-
- 内建函数
- 数学函数
atan2(x, y) x/y的反正切,x和y以弧度为单位 cos(x) x的余弦,x以弧度为单位 exp(x) x的指数函数 int(x) x的整数部分,取靠近零一侧的值 log(x) x的自然对数 rand( ) 比0大比1小的随机浮点值 sin(x) x的正弦,x以弧度为单位 sqrt(x) x的平方根 srand(x) 为计算随机数指定一个种子值
- 字符串函数
asort(s [,d]) 将数组s按数据元素值排序。索引值会被替换成表示新的 排序 顺序的连续数字。另外,如果指定了d,则排序后的数组会存储在数组d中 asorti(s [,d]) 将数组s按索引值排序。生成的数组会将索引值作为数据元素值,用连续数字索引来表明排序顺序。另外如果指定了d,排序后的数组会存储在数组d中 gensub(r, s, h [, t]) 查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果h是一个以g或G开头的字符串,就用s替换掉匹配的文本。如果h是一个数字,它表示要替换掉第h处r匹配的地方 gsub(r, s [,t]) 查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果找到了,就全部替换成字符串s index(s, t) 返回字符串t在字符串s中的索引值,如果没找到的话返回0 length([s]) 返回字符串s的长度;如果没有指定的话,返回$0的长度 match(s, r [,a]) 返回字符串s中正则表达式r出现位置的索引。如果指定了数组a,它会存储s中匹配正则表达式的那部分 split(s, a [,r]) 将s用FS字符或正则表达式r(如果指定了的话)分开放到数组a中。返回字段的总数 sprintf(format,variables) 用提供的format和variables返回一个类似于printf输出的字符串 sub(r, s [,t]) 在变量$0或目标字符串t中查找正则表达式r的匹配。如果找到了,就用字符串s替换掉第一处匹配 substr(s, i [,n]) 返回s中从索引值i开始的n个字符组成的子字符串。如果未提供n,则返回s剩下的部分 tolower(s) 将s中的所有字符转换成小写 toupper(s) 将s中的所有字符转换成大写
- 时间函数
mktime(datespec) 将一个按YYYY MM DD HH MM SS [DST]格式指定的日期转换成时间戳值① strftime(format[,timestamp])将当前时间的时间戳或timestamp(如果提供了的话)转化格式化日期(采用 shell 函数date()的格式) systime( ) 返回当前时间的时间戳
- 数学函数
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Linux 系统编程(第二版)
Robert Love / 东南大学出版社 / 2014-1-1 / 78
如何编写那些直接依赖于Linux内核和核心系统库提供的服务的软件?通过《Linux系统编程(第2版)(影印版)》,Linux内核参与者RobertLove(洛夫)为你提供了Linux系统编程方面的教程,Linux系统调用的参考手册,以及对于如何编写更聪明和更快的代码的来自内部人士的建议。Love清晰地指出了POSIX标准函数和Linux特别提供服务之间的差异。通过关于多线程的新章节,这本修订和扩展......一起来看看 《Linux 系统编程(第二版)》 这本书的介绍吧!