shell编程----awk

Rasine ·
更新时间:2024-11-10
· 530 次阅读

目录标题1. awk2. awk模式匹配3. 记录和域4. 关系和布尔运算符5. 表达式6. 系统变量7. 格式输出8. 内置函数练习 1. awk

  正则表达式的扩展,awk、perl等支持正则表达式扩展出来的一些元字符。

扩展的正则表达式元字符及其意义

符号 意义
匹配0个或1个在其之前的那个普通字符
+ 匹配1个或多个在其之前的那个普通字符
() 表示一个字符集合或用在expr中
| 表示“或”,匹配一组可选的字符
“?”
  匹配之前那个字符0次或1次
  如:jo?b,该表达式表示匹配o字符0次或1次,即匹配job或joob。“?”至多可以匹配1个字符。 “+”
  与“”类似,都是匹配其前面的那个字符多次,但是“”符号可以匹配0次,而“+”符号至少匹配1次。
  如:s+eu表示匹配s1次或任意次,sseu,ssseu等字符串都可由该表达式进行匹配,而seu却不能由s+eu来匹配。 “()”字符和”字符
  “()”符号通常与“|”符号结合使用,表示一组可选字符的集合,如:
re(a|b|c)d 该表达式中(a|b|c)表示在字符a、b、c中选择任意一个字符,即read、rebd、recd都是由该表达式进行匹配。
  事实上,“()”符号很少被使用到,因为“[]”符号完全能够代替“()”符号表示一组可选字符的集合,re(a|b|c)d就等价于re[a|b|c]d
  “|”符号也可以表示多个正则表达式的“或”关系,基本格式为:re1|re2|re3|… 1其中re1,re2和re3表示正则表达式。

  通过awk可以创建程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其它的功能。awk适合文本处理和报表生成,其语法较为常见,借鉴了某些语言的精华,如c语言等。在linux系统日常处理工作中,发挥着很重要的作用,掌握了awk将会使你的工作量变得高大上。
  awk程序由一个主输入循环维持,主输入循环反复执行,直到条件被触发,主输入循环无须由程序员取写,awk已经搭好主输入循环的框架。

2. awk模式匹配

  任何awk语句都有模式(pattern)和动作(action)组成模式是由一组用于测试输入行是否需要执行动作的规则。动作包含语句,函数和表达式的执行过程,简言之,模式决定动作和时触发和触发时间动作执行对输入行的处理。

[root@localhost awk]# sed '=' test1 1 2 3 4 [root@localhost awk]# awk '/^$/{printf "This is a blank line.\n"}' test1 This is a blank line. This is a blank line. This is a blank line. This is a blank line.

将操作写入文件中

[root@localhost awk]# awk -f test1.awk test1 This is a blank line. This is a blank line. This is a blank line. This is a blank line. [root@localhost awk]# cat test1.awk /^$/{printf "This is a blank line.\n"}

直接执行

[root@localhost awk]# ./test1.awk test1 This is a blank line. This is a blank line. This is a blank line. This is a blank line. [root@localhost awk]# cat test1.awk #!/usr/bin/awk -f /^$/{printf "This is a blank line.\n"} 3. 记录和域

  awk认为输入文件是结构化的,awk将每个输入文件行定义为记录,行中的每个字符串定义为域,域之间用空格,Tab键或其它符号进行分隔,分隔域的符号就叫做分隔符。
  awk定义与操作符来指定执行动作的域,域操作符来指定执行动作的域,域操作符来指定执行动作的域,域操作符后面跟数字或变量来标识域的位置,每条记录的域从1开始编号,如$1表示第一个域,$0表示所有域。

$0表示所有域

[root@localhost awk]# awk '{print $0}' test2 jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi

$2,$1,$3,$4

[root@localhost awk]# awk '{print $2,$1,$3,$4}' test2 Zhang jy 8497335 shanxi Zhang jy 8497335 shanxi Zhang jy 8497335 shanxi Zhang jy 8497335 shanxi Zhang jy 8497335 shanxi [root@localhost awk]# awk 'BEGIN {one=1;two=2} {print $(one+two)}' test2 8497335 8497335 8497335 8497335 8497335

tab键被认为是连续的空格键来处理

[root@localhost awk]# cat test2 jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi [root@localhost awk]# awk 'BEGIN {one=1;two=2} {print $(one+two)}' test2 8497335 8497335 8497335 8497335 8497335 8497335 8497335 8497335

用tab键分隔域

[root@localhost awk]# cat test2 jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi [root@localhost awk]# awk -F "\t" '{print $1}' test2 jy jy jy jy jy [root@localhost awk]# awk -F "\t" '{print $2}' test2 Zhang 8497335 shanxi [root@localhost awk]# awk -F "\t" '{print $3}' test2 # \t:表示tab Zhang 8497335 shanxi Zhang 8497335 shanxi Zhang 8497335 shanxi Zhang 8497335 shanxi

注意:不要用多个tab
如果出现多个tab,使用如下命令解决

[root@localhost awk]# cat test2 jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi jy Zhang 8497335 shanxi [root@localhost awk]# awk -F "\t+" '{print $2}' test2 Zhang 8497335 shanxi Zhang 8497335 shanxi Zhang 8497335 shanxi Zhang 8497335 shanxi Zhang 8497335 shanxi [root@localhost awk]# awk 'BEGIN {FS=","} {print $1,$3}' test3 jy 8497335 shanxi jy 8497335 shanxi jy 8497335 shanxi jy 8497335 shanxi jy 8497335 shanxi 4. 关系和布尔运算符

  awk定义了一组关系运算符用于awk模式匹配。

awk关系运算符及其意义

元算符 意义
< 小于
> 大于
<= 小于或等于
>= 大于或等于
== 等于
匹配正则表达式
!~ 不匹配正则表达式

$1匹配第一个域为root的内容

[root@localhost awk]# awk 'BEGIN {FS=":"} $1~/root/' passwd root:x:0:0:root:/root:/bin/bash

所有的域不匹配/root/

[root@localhost awk]# awk 'BEGIN {FS=":"} $0!~/root/' 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 [root@localhost awk]# awk 'BEGIN {FS=":"} {if ($3<$4) print$0}' passwd adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

||表示或 ==是精确匹配

[root@localhost awk]# awk 'BEGIN {FS=":"} {if ($3==1||$4==7) print$0}' passwd bin:x:1:1:bin:/bin:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 5. 表达式

  与其它编程一样,awk表达式用于存储,操作和获取数据。一个awk表达式可由数值,字符常量,变量,操作符,函数和正则表达式自由组合而成。
  变量是一个值的标识符,定义awk变量非常方便,只需要定义一个变量名并将值赋给它们即可。
  变量名只是包含字母,数字和下划线而且不能以数字开通。
  定义awk变量无须生命变量类型,每个变量由两种类型的值:字符串值和数值。
  awk根据表达式上下文来确定使用哪个值。变量的默认值为0,默认字符串值为空。

统计空白数

[root@localhost awk]# awk '/^$/{print x++}' test1 0 1 2 3 [root@localhost awk]# awk '/^$/{print ++x}' test1 1 2 3 4

平均值的计算

[root@localhost awk]# cat test4 jy,Zhang,8497335,77,88,99,100 jy,Zhang,8497335,25,45,15,65 jy,Zhang,8497335,99,55,26,29 jy,Zhang,8497335,77,19,48,53 jy,Zhang,8497335,93,88,84,72 [root@localhost awk]# cat test4.awk #!/usr/bin/awk -f BEGIN {FS=","} {total=$4+$5+$7 avg=total/4 print $1,avg } [root@localhost awk]# chmod o+x test4.awk [root@localhost awk]# ./test4.awk test4 jy 66.25 jy 33.75 jy 45.75 jy 37.25 jy 63.25 6. 系统变量

  awk定义了很多内建变量用于设置环境信息,我们称他为系统变量。
  这些系统变量可分为:第一种用于改变awk的默认值,如域分隔符。第二种用于定义系统值,在处理文本时可以读取这些系统值如记录中的域数量,当前记录数,当前文件名等。
  NF:为记录的域数量
  NR:显示当前的记录数,该值根据读取输入文件的进度而变化,读取第一条记录时,NR=1读取到文件末尾时,NR为该文件包含的记录数。
  $0表示打印记录的所有域
  FILENAME:保存了当前的输入文件名

[root@localhost awk]# awk 'BEGIN {FS=","} {print NF,NR,$0} END {print FILENAME}' test4 7 1 jy,Zhang,8497335,77,88,99,100 7 2 jy,Zhang,8497335,25,45,15,65 7 3 jy,Zhang,8497335,99,55,26,29 7 4 jy,Zhang,8497335,77,19,48,53 7 5 jy,Zhang,8497335,93,88,84,72 test4 7. 格式输出

  前面的例子只涉及awk如何输入文件进行处理,对于输出的格式并未规定。而awk的一大主要功能时产生报表,报表就是要求按照一定的格式输出,awk借鉴c语言的语法,定义了printf输出,它可以规定输出的格式。

[root@localhost awk]# awk 'BEGIN {FS=","} {printf("%s\t%d\n",$2,$7)}' test4 Zhang 100 Zhang 65 Zhang 29 Zhang 53 Zhang 72 [root@localhost awk]# awk 'BEGIN {printf("%c\n",65)}' A [root@localhost awk]# awk 'BEGIN {printf("%f\n",35)}' 35.000000 [root@localhost awk]# awk 'BEGIN {printf("%.3f\n",35)}' 35.000

-10s表示将$1控制在10位,并且时左对齐,如果字符串不足15位使用空格补齐

[root@localhost awk]# awk 'BEGIN {FS=","}{printf("%-10s\t%s\n",$1,$3)}' test4 jy 8497335 jy 8497335 jy 8497335 jy 8497335 jy 8497335 8. 内置函数

  awk提供了强大的内置字符串函数,用于实现文本的字符串替换 查找以及分割等功能
  gsub函数执行字符串替换功能,它将第一个字符串替换位第二个字符串。
  index和length函数。indes返回第二个字符串在第一个字符串出现的首位置length返回字符串的长度。

[root@localhost awk]# awk 'BEGIN {FS=":";OFS=":"} gsub(/root/,"student",$1) {print $0}' passwd student:x:0:0:root:/root:/bin/bash [root@localhost awk]# awk 'BEGIN {FS=":"} gsub(/root/,"student",$1) {print $0}' passwd student x 0 0 root /root /bin/bash [root@localhost awk]# awk 'BEGIN {print index("zjylilhahahxixi","ha")}' 7 [root@localhost awk]# awk 'BEGIN {print length("zjylilhahahxixi")}' 15 练习 输出本机的ip地址 hostname -I 输出本机的根分区使用率 [root@localhost ~]# df -h| awk '/\/dev\/vda1/{print $5}' 68% [root@localhost ~]# df -h | awk '{if ($6=="/") print$5}' 68% 以passwd文件为例,输出其中以bash结尾的完整记录 [root@localhost awk]# awk '/bash$/{print$0}' passwd root:x:0:0:root:/root:/bin/bash student:x:1000:1000:Student User:/home/student:/bin/bash 列出以ro开头的用户记录 [root@localhost awk]# awk '/^ro/{print$0}' passwd root:x:0:0:root:/root:/bin/bash 输出以a,b,c或着d开头的用户名,宿主目录 [root@localhost awk]# awk 'BEGIN {FS=":"} /^(a|b|c|d)/{print $1,$6}' passwd bin /bin daemon /sbin adm /var/adm dbus / avahi /var/run/avahi-daemon avahi-autoipd /var/lib/avahi-autoipd chrony /var/lib/chrony colord /var/lib/colord abrt /etc/abrt apache /usr/share/httpd dhcpd / 输出其中用名以a开头,登陆shell以nologin结尾的用户名,登陆shell [root@localhost awk]# awk '/^a/&&/nologin$/' passwd adm:x:3:4:adm:/var/adm:/sbin/nologin avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin 输出第三行的用户记录 [root@localhost awk]# awk '{if (NR==3) print$0}' passwd daemon:x:2:2:daemon:/sbin:/sbin/nologin 输出奇数(行号NR除以2余数为1)行的用户记录 [root@localhost awk]# awk '{if (NR%2!=0) print$0}' passwd root:x:0:0:root:/root:/bin/bash daemon:x:2:2:daemon:/sbin:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown mail:x:8:12:mail:/var/spool/mail:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin ovirtagent:x:175:175:RHEV-M Guest Agent:/usr/share/ovirt-guest-agent:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin student:x:1000:1000:Student User:/home/student:/bin/bash colord:x:997:995:User for colord:/var/lib/colord:/sbin/nologin libstoragemgmt:x:996:994:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin qemu:x:107:107:qemu user:/:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin radvd:x:75:75:radvd user:/:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin dhcpd:x:177:177:DHCP server:/:/sbin/nologin 输出偶数(行号除以2余数为0)行的用户记录 [root@localhost awk]# awk '{if (NR%2==0) print$0}' passwd bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync halt:x:7:0:halt:/sbin:/sbin/halt operator:x:11:0:operator:/root:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin chrony:x:998:996::/var/lib/chrony:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin unbound:x:995:993:Unbound DNS resolver:/etc/unbound:/sbin/nologin saslauth:x:994:76:"Saslauthd user":/run/saslauthd:/sbin/nologin rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin gnome-initial-setup:x:993:991::/run/gnome-initial-setup/:/sbin/nologin apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
作者:weixin_43384009



awk shell编程 shell

需要 登录 后方可回复, 如果你还没有账号请 注册新账号