本文共 12427 字,大约阅读时间需要 41 分钟。
awk - pattern scanning and processing language
基本用法:gawk [option] 'program' FILE ...
program: PATTERN{ACTION STATEMENTS}语句之间用分号分隔print,printf 选项:-F: 指明输入时用到的分隔符:-v var=value 自定义变量:1、 print print item1, item2, ... 要点: (1)逗号分隔符: (2)输出的各item可以字符串,也可以是数值:当前记录的字段、变量或awk的表达式: (3)如省略item,相当于print $02、 变量 2.1 内建变量 FS: 输入字段分隔符, 默认为空白字符 OFS: 输出字段分隔符, 默认为空白字符 RS: 输入时的换行符 ORS: 输出时的换行符 NF: 字段数量 {print NF} {print $NF} NR: 行数 FNR: 各文件分别计数: 行数: FILENAME: 当前文件名: ARGC: 命令行参数的个数: ARGV: 数组,保存的是命令行所给定的各参数: 2.2 自定义变量 (1)-v var=value 变量名区分字符大小写: (2)在program中直接定义3、printf命令 格式化输出:printf FORMAT, item1, item2, ... (1)FORMAT必须给出; (2)不会自动换行,需要显示给出换行控制符, \n (3)FORMAT 中需要分别为后面的每一个item指定一个格式化符号: 格式符: %c 显示字符的ASCII码 %d %i 显示十进制整数 %e %E 科学计数法数值显示 %f 显示为浮点数 %g %G 以科学计数法或浮点形式显示数值 %s 显示字符串 %u 无符号整数 %% 显示%自身 修饰符: #[.#] 第一个数字控制显示的宽度: 第二个#表示小数点后的精度: %3.1f - 左对齐 + 显示数值的符号4、操作符 算术操作符: x+y, x-y, x*y, x/y, X^y, x%y -x +x: 转换为数值: 字符串操作符: 没有符号的操作符,字符串连接 赋值操作符: =, +=, -=,*=, /=, %=, ^= ++, -- 比较操作符: >, >=, <, <=, !=, == 模式匹配符: ~ 左边是否匹配右边 !~ 左边是否不匹配右边 逻辑操作符: && || ! 函数调用: function_name(argu1, argu2, ...) 条件表达式: selector?if-true-expression:if-false-expression
[root@centos7 ~]#awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%s\n",$1,usertype}' /etc/passwd
root:Sysadmin or SysUserbin:Sysadmin or SysUserdaemon:Sysadmin or SysUseradm:Sysadmin or SysUserlp:Sysadmin or SysUsersync:Sysadmin or SysUsershutdown:Sysadmin or SysUserhalt:Sysadmin or SysUsermail:Sysadmin or SysUseroperator:Sysadmin or SysUsergames:Sysadmin or SysUserftp:Sysadmin or SysUsernobody:Sysadmin or SysUserpegasus:Sysadmin or SysUsersystemd-network:Sysadmin or SysUser5、PATTERN (1)empty: 空模式,匹配每一行: (2)/regular expression/: 仅处理能够被此处的模式匹配到的行: [root@centos7 ~]#awk '/^UUID/{print $1}' /etc/fstab UUID=576ed6fe-d3e8-403d-832f-2dc117ba8d2f UUID=6e6694fc-5a2f-47a1-b96b-509621e5fc1e UUID=1828df2b-47f3-442d-9681-ca17539861d9 UUID=111bb92e-4d79-486a-afaf-38ba79856d30 [root@centos7 ~]#awk '!/^UUID/{print $1}' /etc/fstab // !表示取反 # # (3)relation expression: 关系表达式: 结果有真有假:结果为真才会被处理: 真:结果为非0值,非空字符串: [root@centos7 ~]#awk -F: '$3>=1000{print $1,$3}' /etc/passwd nfsnobody 65534 xp018970 1000 [root@centos7 ~]#awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd root /bin/bash xp018970 /bin/bash (4)line range: 行范围 startline,endline: /pattern1/,/pattern2/ [root@centos7 ~]#awk -F: '(NR>=3&&NR<=10){print $1}' /etc/passwd daemon adm lp sync shutdown halt mail operator (5)BEGIN/END模式 BEGIN{}: 仅在开始(处理文件中的文本)之前执行一次: END{}:仅在文本处理完成之后执行一次:
[root@centos7 ~]#awk -F: 'BEGIN{print "Username Uid \n============================"}{printf "%-19s|%d\n", $1,$3}END{print "============================ \n END "}' /etc/passwd
Username Uid ============================ root |0 bin |1 daemon |2 adm |3 lp |4 sync |5 shutdown |6 halt |7 mail |8 operator |11 games |12 ftp |14 nobody |99 pegasus |66 systemd-network |192 dbus |81 polkitd |999 unbound |998 libstoragemgmt |997 rpc |32 colord |996 saslauth |995 abrt |173 setroubleshoot |994 rtkit |172 pulse |171 rpcuser |29 nfsnobody |65534 named |25 radvd |75 qemu |107 chrony |993 mysql |27 tss |59 geoclue |992 hacluster |189 usbmuxd |113 cockpit-ws |991 gluster |990 gdm |42 gnome-initial-setup|989 sshd |74 avahi |70 postfix |89 ntp |38 tcpdump |72 xp018970 |1000 dovecot |97 dovenull |988 ============================ END 6、 控制语句 if(condition){statements} if(condition){stations} else {statements} while(condition){stations} do {statements} while(condition) for(expr1;expr2;expr3) {statements} break continue delete array exit { statements } 6.1 if-else 语法:if(condition){stations} else {statements} [root@centos7 ~]#awk -F: '{if($3>=1000) print $1,$3}' /etc/passwd nfsnobody 65534 xp018970 1000 [root@centos7 ~]#awk -F: '{if($3>=1000) {printf "%19s : Common User\n",$1} else {printf "%19s : root or Sysuser\n", $1} }' /etc/passwd root : root or Sysuser bin : root or Sysuser daemon : root or Sysuser adm : root or Sysuser lp : root or Sysuser sync : root or Sysuser shutdown : root or Sysuser [root@centos7 ~]#awk -F: '{if($NF=="/bin/bash") printf "%8s:%s \n", $1,$NF}' /etc/passwd root:/bin/bash xp018970:/bin/bash [root@centos7 ~]#awk '{if(NF>5) print $0}' /etc/fstab //默认为空白字符为分隔符,字段数大于5,就打印整行 [root@centos7 ~]#df -h |awk -F '[[:space:]]+|%' '/^\/dev/ {print $1,$5}' |awk '{if($2>=80) printf "WarningDisk : %s\n", $1}' WarningDisk : /dev/sr0 [root@centos7 ~]#df -h |awk -F '[[:space:]]+|%' '$0 ~ "^/dev" {print $1,$5}' |awk '$2>=80{print $1}' /dev/sr0 [root@centos7 ~]#df -h |awk -F"%" '/^\/dev/{print $1}' | awk '{if($NF>=30) printf "warning disk:%s\n", $1}' warning disk:/dev/sda3 warning disk:/dev/sr0 使用场景:对awk取得的整数行或某个字段做条件判断: 6.2 while 循环 语法:while(condition)statement 条件“真”,进入循环: 条件“假”,退出循环: 使用场景:对一行内的多个字段逐一类似处理时使用:对数组中的各元素逐一处理时使用: [root@centos7 ~]#awk '/^[[:space:]]*linux16/ {i=1;while(i=7) {print $i,length($i)};i++ }}' /etc/grub2.cfg linux16 7 /vmlinuz-4.20.3-1.0-xinzhoulinux 32 root=UUID=576ed6fe-d3e8-403d-832f-2dc117ba8d2f 46 crashkernel=auto 16 linux16 7 /vmlinuz-3.10.0-862.el7.x86_64 30 root=UUID=576ed6fe-d3e8-403d-832f-2dc117ba8d2f 46 crashkernel=auto 16 linux16 7 /vmlinuz-0-rescue-18ed42c1c89e4d28870e69320e88d637 50 root=UUID=576ed6fe-d3e8-403d-832f-2dc117ba8d2f 46 crashkernel=auto 16 6.3 do-while 循环 语法:do statement while (condition) 意义:至少执行一次循环体 6.4 for循环 语法:for(expr1;expre2;expr3) statement for(variable assignment;condition;iteration process) {for-body} [root@centos7 ~]#awk '/^[[:space:]]*linux16/ {for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg linux16 7 /vmlinuz-4.20.3-1.0-xinzhoulinux 32 root=UUID=576ed6fe-d3e8-403d-832f-2dc117ba8d2f 46 ro 2 crashkernel=auto 16 rhgb 4 quiet 5 LANG=en_US.UTF-8 16 linux16 7 特殊用法: 能够遍历数组中的元素: 语法:for(var in array) {for-body}7、array 关联数组:array[index-expression] index-expression: (1)可使用任何字符串:字符串要使用双引号: (2)如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”: 若要判断数组中是否存在某元素,要使用“index in array”格式进行: weekdays["mon"]="Monday" [root@centos7 ~]#awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}' Monday [root@centos7 ~]#awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["tue"]}' Tuesday [root@centos7 ~]#awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}' Tuesday Monday 注意:var会遍历array中的每个索引:
[root@centos7 ~]#tail -4 /etc/fstab |awk '{print "hello: " $1,$2}'
hello: UUID=576ed6fe-d3e8-403d-832f-2dc117ba8d2f /hello: UUID=6e6694fc-5a2f-47a1-b96b-509621e5fc1e /boothello: UUID=1828df2b-47f3-442d-9681-ca17539861d9 /datahello: UUID=111bb92e-4d79-486a-afaf-38ba79856d30 swap[root@centos7 ~]#awk -v FS=':' '{print $1}' /etc/passwd
rootbindaemonadmlpsyncshutdownhaltmailoperatorgamesftpnobodypegasus[root@centos7 ~]#awk -v FS=':' -v OFS='=====' '{print $1,$3,$7}' /etc/passwd //FS: 输入字段分隔符, 默认为空白字符 OFS: 输出字段分隔符, 默认为空白字符
root=====0=====/bin/bashbin=====1=====/sbin/nologindaemon=====2=====/sbin/nologinadm=====3=====/sbin/nologinlp=====4=====/sbin/nologinsync=====5=====/bin/syncshutdown=====6=====/sbin/shutdownhalt=====7=====/sbin/haltmail=====8=====/sbin/nologinoperator=====11=====/sbin/nologingames=====12=====/sbin/nologin[root@centos7 ~]#awk -v RS=' ' '{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologingames:x:12:100:games:/usr/games:/sbin/nologinftp:x:14:50:FTPUser:/var/ftp:/sbin/nologinnobody:x:99:99:Nobody:/:/sbin/nologinpegasus:x:66:65:tog-pegasusOpenPegasus[root@centos7 ~]#awk -v RS=' ' -v ORS='###' '{print}' /etc/passwd // RS: 输入时的换行符 ORS: 输出时的换行符
root:x:0:0:root:/root:/bin/bashgames:x:12:100:games:/usr/games:/sbin/nologinftp:x:14:50:FTP###User:/var/ftp:/sbin/nologinnobody:x:99:99:Nobody:/:/sbin/nologinpegasus:x:66:65:tog-pegasus###OpenPegasus###WBEM/CIM###services:/var/lib/Pegasus:/sbin/nologinsystemd-network:x:192:192:systemd###Network###Management:/:/sbin/nologin[root@centos7 ~]#awk '{print NF}' /etc/fstab //NF: 字段数量
01210191216666[root@centos7 ~]#awk '{print NR}' /etc/fstab //NR: 行数
12345678910[root@centos7 ~]#awk '{print FNR}' /etc/fstab /etc/issue //FNR: 各文件分别计数: 行数:
123456789101112123[root@centos7 ~]#awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue //ARGC: 命令行参数的个数:
3[root@centos7 ~]#awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/issue //ARGV: 数组,保存的是命令行所给定的各参数:
awk[root@centos7 ~]#awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/issue //ARGV: 数组,保存的是命令行所给定的各参数:/etc/fstab[root@centos7 ~]#awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue //ARGV: 数组,保存的是命令行所给定的各参数:/etc/issue[root@centos7 ~]#awk -v test="hello world" 'BEGIN{print test}'
hello world[root@centos7 ~]#awk 'BEGIN{test="hello world";print test}' hello world[root@centos7 ~]#awk -F: '{printf "Username: %s Uid: %d\n", $1,$3}' /etc/passwd //格式符用法
Username: root Uid: 0Username: bin Uid: 1Username: daemon Uid: 2Username: adm Uid: 3Username: lp Uid: 4Username: sync Uid: 5Username: shutdown Uid: 6Username: halt Uid: 7Username: mail Uid: 8Username: operator Uid: 11[root@centos7 ~]#awk -F: '{printf "Username: %19s Uid: %d\n", $1,$3}' /etc/passwd //格式符,修饰符, 默认右对齐
Username: root Uid: 0Username: bin Uid: 1Username: daemon Uid: 2Username: adm Uid: 3Username: lp Uid: 4Username: sync Uid: 5Username: shutdown Uid: 6Username: halt Uid: 7Username: mail Uid: 8Username: operator Uid: 11Username: games Uid: 12Username: ftp Uid: 14Username: nobody Uid: 99Username: pegasus Uid: 66Username: systemd-network Uid: 192[root@centos7 ~]#awk -F: '{printf "Username: %-19s Uid: %d\n", $1,$3}' /etc/passwd // 19字符串的宽度, 加- 左对齐显示
Username: root Uid: 0Username: bin Uid: 1Username: daemon Uid: 2Username: adm Uid: 3Username: lp Uid: 4Username: sync Uid: 5Username: shutdown Uid: 6Username: halt Uid: 7Username: mail Uid: 8Username: operator Uid: 11Username: games Uid: 12Username: ftp Uid: 14Username: nobody Uid: 99Username: pegasus Uid: 66转载于:https://blog.51cto.com/8845692/2346265