标签:双引号 ack 意思 login back 怎么 new var expect
AWK的内容也太多了,简单的做一个复习,都差点要了老命!
awk的作用就是取列、取列并计算,当我们一想到取列或者取列计算的时候就应当立马想到 awk,另外,awk还相当不要脸的包揽了它二弟和它三弟的部分工作,让我很是焦灼,在我 使用的时候不知道用哪个好!
AWK的用户与sed的用法相似,它的语法是这样的:
awk <选项> ‘找谁{干啥}‘ #一定要注意引号是英文的单引号
awk的选项其实比较少,常用就是-F,用来指定分隔符,最让人无语的是分隔符其也可以指 定多个!
1 [root@centos7 ~]# awk ‘NR>=2{print}‘ /etc/passwd #非常简单,符号可以随意换, 比如大于、大于等于、小于、小于等于,等于
1 [root@centos7 ~]# ip a s ens33 | awk ‘NR==3{print $2}‘ #意思是给老子打印出第三行的第二列 2 192.168.80.200/24 3 #awk默认以一个或连续多个空格,TAB,连续多个TAB为分隔符,所以这里面不指定分隔符,默认就是以空格为分隔符的。 1 [root@centos7 ~]# ip a s ens33 | awk ‐F‘[ /]+‘ ‘NR==3{print $3}‘ 2 192.168.80.200 3 #指定多个分隔符,并指定了次数,一次或多次,也就说使用了[]之后,连续之意失效了,需要手动通过扩展的正则表达式加号强调。
使用awk的注意点:
1. 一定要用单引号,三剑客最好都要使用单引号,不然会出各种奇怪的事情!
2. 分隔符可以指定多个,如果不指定的的话,默认就是以空格或连续的空格,TAB或 者连续的TAB为分隔符的。
3. awk的选项使用的不多,最常用的选项就是指定分隔符,即-F的选项,偶尔会用 到-v OFS,不过很少。
4. “干啥”的选项也比较少,最常用的也就是p,即print打印,默认就是print打 印。
5. awk本来就支持扩展的正则表达式,无需像sed一样加r
行:
NR是number is recored的缩写,其实就是行号的意思,如上面 的例子所示。
$0代表的是一整行,$1代表的就不是第一行了,$1代表的就是第一列,其实我们把$0理解 成所有列就很自然了,END代表的最后一列,我们下面有例子。
1 [root@centos7 ~]# awk ‐F‘:‘ ‘NR==1{print $0}‘ /etc/passwd #如果不指定是第一行NR==1,它默认就会把文件里面的第一列全部给你打印出来 2 root:x:0:0:root:/root:/bin/bash 3 [root@centos7 ~]# awk ‘END{print $0}‘ /etc/passwd #END代表最后一行,打印最后一行,{print $0}是默认的,即使不写,效果也是一样的。 4 zhanghe:x:1000:1000:zhanghe:/home/zhanghe:/bin/bash 5 [root@centos7 ~]# awk ‘END{print}‘ /etc/passwd #你看,不加‘$0‘,效果是一样的,END(print $0) 相当于 END (print) 6 zhanghe:x:1000:1000:zhanghe:/home/zhanghe:/bin/bash #sed ‐n ‘$p sed也可以实现这样的效果
那如果我想要第2行以后的行呢?就正常写就行,如下
1 [root@centos7 ~]# awk ‘NR>=2{print}‘ /etc/passwd #非常简单,符号可以随意换,比如大于、大于等于、小于、小于等于,等于
行号也可以单独的使用,比如我想显示出/etc/passwd的行号,也就说想要实现cat -n /etc/passwd和less -N /etc/passwd的功能
1 [root@centos7 ~]# awk ‘{print NR}‘ /etc/passwd #这样仅把所有的行号打印出来了 2 1 3 2 4 3 5 4 6 …… 7 [root@centos7 ~]# awk ‘{print NR,$0}‘ /etc/passwd #在行号后面再加一个$0,$0啥意思还记得吗?代表所有列,行号加上显示所有列就会有cat ‐n的效果了。 8 1 root:x:0:0:root:/root:/bin/bash 9 2 bin:x:1:1:bin:/bin:/sbin/nologin 10 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 11 ……
其实,sed能做取行操作,awk也能做,比如:
1 [root@centos7 ~]# sed ‐n 2p /etc/passwd #打印第二行 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 [root@centos7 ~]# awk ‘NR==2{print}‘ /etc/passwd #打印第二行 4 bin:x:1:1:bin:/bin:/sbin/nologin
列:
上述例子当中的“$数字”的意思其实就是取哪一列,‘print $3’其实就是取第3列,如果 我们想取多列呢?比如我想取出/etc/passwd文件文件当中第1列和第3列,怎么搞呢?
1 [root@centos7 ~]# awk ‐F‘:‘ ‘END{print $1,$3}‘ /etc/passwd #取最后一行的第一列和最后三列 2 zhanghe 1000
那如果我们想取最后一列呢?我们知道END代表最后一列,最后一列用NF来表示,如下所 示:
1 [root@centos7 ~]# awk ‐F‘:‘ ‘NR==1{print $NF}‘ /etc/passwd #最第一行的最后一列 2 /bin/bash
取最后一列,会用到什么地方呢?比如,日志文件,/var/log/secure文件下的日志的长度 并不是固定的,在取日志记录的最后一部分的时候,我们可以用到取最后一列。 那取倒数第二列呢?
1 [root@centos7 ~]# awk ‐F‘:‘ ‘NR==1{print $NF‐1}‘ /etc/passwd #这样写不行,需要加上一个括号,如下所示: 2 ‐1 3 [root@centos7 ~]# awk ‐F‘:‘ ‘NR==1{print $(NF‐1)}‘ /etc/passwd 4 /root 5 [root@centos7 ~]# echo 66 77 88 | awk ‘{print $NF‐1}‘ 6 87 7 [root@centos7 ~]# echo 66 77 88 | awk ‘{print $(NF‐1)}‘ 8 77
其实取列的时候还可以进行比较呢?比如 ,我想要找到/etc/passwd当中第三列大于500的 行。
1 [root@centos7 ~]# awk ‐F‘:‘ ‘$3>500{print $0}‘ /etc/passwd #后面的{print$0}是可以省略的。
案例一:显示磁盘使用率大于10%的分区和挂载点
1 [root@centos7 ~]# df ‐h | awk ‘$5>10%‘ #列比较的时候不能识别%号 2 awk: cmd. line:2: $5>10% 3 awk: cmd. line:2: ^ unexpected newline or end of string 4 [root@centos7 ~]# df ‐h | awk ‘$5>10‘ #不加%,会不准,你看,下面把8%的也显示 出来了,下面有解释 5 文件系统 容量 已用 可用 已用% 挂载点 6 /dev/mapper/centos_centos7‐root 50G 3.9G 47G 8% / 7 /dev/sda1 1014M 179M 836M 18% /boot 8 [root@centos7 ~]# df ‐h | sed ‘s@%@@g‘ | awk ‘$5>10{print $1,$NF}‘ #通过sed把%全都删除 9 文件系统 挂载点 10 /dev/sda1 /boot 11 [root@centos7 ~]# df ‐h | sed ‘s@%@@g‘ | awk ‘$5>10{print $1,$NF}‘ | tai l ‐1 #这样的结果就正常了。 12 /dev/sda1 /boot
为什么会出现不准的情况?其实并不是不准,LINUX系统不会骗我们的,只不过,它默认不 是按照我们以为的方式在比大小,如下所示:
1 [root@centos7 ~]# seq 10 #生成10个数 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 11 10 12 [root@centos7 ~]# seq 10 | sort #使用sort对它们进行排序,结果2比10大?这是怎么回事?是因为linux在比较大小的时候默认是按位进行比较的, 13 1 14 10 15 2 16 3 17 4 18 5 19 6 20 7 21 8 22 9 23 [root@centos7 ~]# seq 10 | sort ‐n #加一个‐n的参数,就是按照数字的大小进行排序,你看,这又恢复正常了。 24 1 25 2 26 3 27 4 28 5 29 6 30 7 31 8 32 9 33 10
如果问题再难一点,显示出磁盘使用率大于10%且小于50%的磁盘分区和挂载点呢?就用 &&符号就行,&&就是并且的意思嘛!如下所示:
1 [root@centos7 ~]# df ‐h | sed ‘s@%@@g‘ | awk ‘$5>10&&$5<50{print $1,$NF}‘ | tail ‐1 2 /dev/sda1 /boot
我们在看行的时候也可以使用,我们我们想看第三行到第六行中间的行:
1 [root@centos7 ~]# awk ‘NR>3&&NR<6{print NR,$0}‘ /etc/passwd 2 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 3 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 1 [root@centos7 ~]# sed ‐n ‘4,5p‘ /etc/passwd 2 adm:x:3:4:adm:/var/adm:/sbin/nologin 3 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
做为条件 我们上面在描述条件的时候都是用的行号,其实我们还可以使用正则表达式做为条件。 比如1:过滤出包含数字的行
1 [root@centos7 test.dir]# cat test.txt 2 zhanghe 3 zhanghe6 4 [root@centos7 test.dir]# awk ‘/[0‐9]/‘ test.txt #awk在使用正则表达式做为条件的时候要用//号的,完整的写法是这样的‘/[0‐9]/{print $0}‘ 5 zhanghe6 6 [root@centos7 test.dir]# grep ‘[0‐9]‘ test.txt 7 zhanghe6
比如2:过滤出/etc/passwd当中开关是root一直到结尾是shutdown之间的行
‘/^root/,/shutdown$/p‘ 效果一样,只不过awk不用加p 2 root:x:0:0:root:/root:/bin/bash 3 …… 4 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
比如3:过滤出/etc/passwd当中开关是root一直到结尾是shutdown之间的行的最后一列
#这一个sed就无法实现了。 2 /bin/bash 3 …… 4 /sbin/shutdown
比如4:显示出最后一列是bash的用户名,下面这个最是骚气,直接指定去匹配哪一个列
1 [root@centos7 ~]# awk ‐F‘:‘ ‘$NF~/bash$/{print $1}‘ /etc/passwd 2 root 3 zhanghe
比如1:显示以一个z或者一个r开头的用户名
1 [root@centos7 ~]# awk ‐F‘:‘ ‘$1~/^(r|z)/{print $1}‘ /etc/passwd #也可以这样写:awk ‐F‘:‘ ‘$1~/^[rz]/{print $1}‘ 2 root 3 rpc 4 rtkit 5 radvd 6 rpcuser 7 zhanghe
注意:^在grep和sed当中只能表示以什么什么开头的行,在awk当中可以通过前而的列表 示某一列当中以什么开头的行,也就是说范围增加了。 比如2:显示UID号码最为一位是1或是5的全名
1 [root@centos7 ~]# awk ‐F‘:‘ ‘$3~/[15]$/{print $1}‘ /etc/passwd 2 bin 3 sync 4 operator 5 dbus 6 pulse 7 radvd 8 unbound 9 setroubleshoot 1 [root@centos7 ~]# awk ‐F‘:‘ ‘{print $3,$4}‘ /etc/passwd | head ‐4 2 0 0 3 1 1 4 2 2 5 3 4 6 [root@centos7 ~]# awk ‐F‘:‘ ‘{print "#"$3"#"$4}‘ /etc/passwd | head ‐4 #可以在里面加点东西,要用双引号才可以,双引号里面有什么,就会原封不动的显示什么。 7 #0#0 8 #1#1 9 #2#2 10 #3#4
用awk做sed的替换功能 用gsub函数,用法:{gsub (/:/,"$")} 将双竖线的内容替换为双引号里面的内容
1 [root@centos7 ~]# awk ‘{gsub (/:/,"$");print}‘ /etc/passwd | head ‐4 2 root$x$0$0$root$/root$/bin/bash 3 bin$x$1$1$bin$/bin$/sbin/nologin 4 daemon$x$2$2$daemon$/sbin$/sbin/nologin 5 adm$x$3$4$adm$/var/adm$/sbin/nologin 1 [root@centos7 ~]# awk ‘{gsub (/r/,"R") $1;print}‘ /etc/passwd | head ‐4 #精确替换哪一列的什么 2 Root:x:0:0:Root:/Root:/bin/bash 3 bin:x:1:1:bin:/bin:/sbin/nologin 4 daemon:x:2:2:daemon:/sbin:/sbin/nologin 5 adm:x:3:4:adm:/vaR/adm:/sbin/nologin 6 [root@centos7 ~]# awk ‘{gsub (/:/,"$");print}‘ /etc/passwd | head ‐4 #不指定哪一列就是一整行,相当于$0,也就是所有列 7 root$x$0$0$root$/root$/bin/bash 8 bin$x$1$1$bin$/bin$/sbin/nologin 9 daemon$x$2$2$daemon$/sbin$/sbin/nologin 10 adm$x$3$4$adm$/var/adm$/sbin/nologin
显示人名和UID,然后以逗号分隔,就用最简单的方式即可
1 [root@centos7 ~]# awk ‐F‘:‘ ‘{print $1,$3}‘ /etc/passwd | head ‐4 2 root 0 3 bin 1 4 daemon 2 5 adm 3 6 [root@centos7 ~]# awk ‐F‘:‘ ‘{print $1","$3}‘ /etc/passwd | head ‐4 7 root,0 8 bin,1 9 daemon,2 10 adm,3
记住:
1. BEGIN里面的内容会在awk读取文件之前执行,一般来用计算。
2. END里面的内容会有awk读取文件之后执行,一般用来做统计。
BEGIN:
1 [root@centos7 ~]# awk ‘BEGIN{print 1+2,1‐8}‘ 2 3 ‐7 3 [root@centos7 ~]# awk ‐F‘:‘ ‘BEGIN{OFS="$$$"}{print $1,$2}‘ /etc/passwd | head ‐4 #也可以用来修改变量,相当于上面讲的‐v OFS 4 root$$$x 5 bin$$$x 6 daemon$$$x 7 adm$$$x
END: 什么时候用END?统计的时候,先进行计算,最后END()显示最后结果,其实这才是 awk最重要的功能,awk原名文本报名生成器,用来生成报告用的,生成报告的话一定会用 到统计了。
"!!!!"}‘ /etc/passwd | tail ‐4 #这个例子主要体会一下END的内容会在读取文件内容之 后执行。 2 ntp$$$x 3 tcpdump$$$x 4 zhanghe$$$x 5 !!!!
再来一个例子: 统计/etc//services 文件当中空行的数量 i=i+1 相当于i++ 用来出现的总次数,初始值是0.
1 [root@centos7 tmp]# awk ‘/^$/{i++;print i}‘ /tmp/test.sh #有5个空行,这不是我想要的结果 2 1 3 2 4 3 5 4 6 5
1 [root@centos7 tmp]# awk ‘/^$/{i++}END{print i}‘ /tmp/test.sh #完成之后再打开出变量i,这里的变量i已经增长到5了,这时候打印出来正合适呢! 2 5
求和:i=i+$,相当于i+=$
和:i=i+$,相当于i+=$ 1 [root@centos7 tmp]# cat test.txt 2 12 3 11 4 14 5 [root@centos7 tmp]# awk ‘{sum += $1};END{print sum}‘ test.txt #对第一列进行求和 6 37 1 [root@centos7 tmp]# cat test.txt 2 12 45 3 11 11 4 14 13 5 [root@centos7 tmp]# awk ‘{sum += $2};END{print sum}‘ test.txt #对第二列进行求和 6 69 1 [root@centos7 tmp]# cat test.txt 2 aaa 12 45 3 aaa 11 11 4 aaa 14 13 5 bbb 1 2 6 [root@centos7 tmp]# awk ‘/aaa/{sum += $3}END{print sum}‘ test.txt #对符号条件的行进行求和 7 69
上
标签:双引号 ack 意思 login back 怎么 new var expect
原文地址:https://www.cnblogs.com/yizhangheka/p/11734186.html