@mrz1
2018-01-04T09:03:46.000000Z
字数 14196
阅读 973
笔记
格式化输出:printf "FORMAT", item1, item2, ...(1) 必须指定FORMAT(2) 不会自动换行,需要显式给出换行控制符,\n(3) FORMAT中需要分别为后面每个item指定格式符格式符:与item一一对应%c: 显示字符的ASCII码%d, %i: 显示十进制整数%e, %E:显示科学计数法数值(10的几次方)%f:显示为浮点数%g, %G:以科学计数法或浮点形式显示数值%s:显示字符串%u:无符号整数%%: 显示%自身修饰符:#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f-: 左对齐(默认右对齐)%-15s+:显示数值的正负符号%+d
awk -F: '{printf "%s",$1}' /etc/passwd //不换行显示userawk -F: '{printf "%s\n",$1}' /etc/passwd //换行显示user[root@centos7 ~]#awk -F: '{printf "Username:%s\n",$1}' /etc/passwdUsername:rootUsername:binUsername:daemon[root@centos7 ~]#awk -F: '{printf "username:%s|uid:%d\n",$1,$3}' /etc/passwdusername:root|uid:0username:bin|uid:1username:daemon|uid:2[root@centos7 ~]#awk -F: '{printf "%-30s|%10d\n",$1,$3}' /etc/passwd //正数右对齐负数左对齐root |0bin |1daemon |2[root@centos7 ~]#awk -v n=123.456789 'BEGIN{printf "%9.4f",n}'123.4568 //有一个空格n是9位数1-9;保留四位123.4568(约等于)宽度九位 所以前面是一个空格[root@centos7 ~]#awk -v n=123.456789 'BEGIN{printf "%9.5f",n}'123.45679 //没有空格n是9位数1-9;保留五位123.45679(约等于)宽度九位 所以前面没有空格[root@centos7 ~]#awk -v n=123.456789 'BEGIN{printf "%9.2f",n}'123.46 //有三个个空格n是9位数1-9;保留二位123.46(约等于)宽度九位 所以前面是三个空格
算术操作符x+y, x-y, x*y, x/y, x^y, x%y-x: 转换为负数+x: 转换为数值字符串操作符:没有符号的操作符,字符串连接赋值操作符:=, +=, -=, *=, /=, %=, ^=++, --下面两语句有何不同[root@centos7 ~]#awk 'BEGIN{i=0;print ++i,i}'1 1[root@centos7 ~]#awk 'BEGIN{i=0;print i++,i}'0 1实例:[root@centos7 ~]#awk -v m=10 -v n=2 'BEGIN{printf m/n}'5[root@centos7 ~]#awk -v m=10 -v n=2 'BEGIN{printf m-n}'8[root@centos7 ~]#awk -v m=10 -v n=2 'BEGIN{printf m^n}'100[root@centos7 ~]#awk -v m=10 -v n=3 'BEGIN{printf m%n}' 取模1[root@centos7 ~]#awk -v m=10 -v n=3 'BEGIN{printf m*=n}'30
比较操作符:==, !=, >, >=, <, <=模式匹配符:~:左边是否和右边匹配包含!~:是否不匹配示例:awk -F: '$0 ~ /root/{print $1}' /etc/passwd //查看包含root的行[root@centos7 ~]#awk '$0~"^bin" {print $1}' /etc/passwdbin:x:1:1:bin:/bin:/sbin/nologin[root@centos7 ~]#awk '$0~"^root"' /etc/passwdroot:x:0:0:root:/root:/bin/bash[root@centos7 ~]#awk '$0~"^bin"' /etc/passwdbin:x:1:1:bin:/bin:/sbin/nologin[root@centos7 ~]#awk '$0 ~ /^(root|bin)/' /etc/passwdroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologinawk '$0 !~ /root/' /etc/passwd //不包含root[root@centos7 ~]#awk -F: '$3==0' /etc/passwdroot:x:0:0:root:/root:/bin/bash[root@centos7 ~]#awk -F: '$3>=1000' /etc/passwdnfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologinfei:x:1000:1000:fei:/home/fei:/bin/bashlili:x:1001:1001::/home/lili:/bin/bash""或者// 里面的表示正则[root@centos7 ~]#awk -F: 'i' /etc/issue[root@centos7 ~]#awk -F: -v i=0 'i' /etc/issue[root@centos7 ~]#awk -F: -v i="" 'i' /etc/issue[root@centos7 ~]#awk -F: -v i=" " 'i' /etc/issueThe hostname is \ntime is \ttty is \l\SKernel \r on an \m注意:i只要有值就打印(0,"" 未定义不包括在内)
逻辑操作符:与&&,或||,非!示例:awk -F: '$3>=0 && $3<=1000 {print $1}' /etc/passwd[root@centos7 ~]#awk -F: '$3>=0 && $3<=1 {print $1}' /etc/passwdrootbinawk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd[root@centos7 ~]#awk -F: '$3==0 || $3<=2 {print $1}' /etc/passwdrootbindaemonawk -F: '!($3==0){print $1}' /etc/passwd[root@centos7 ~]#awk -F: '!($3!=0){print $0}' /etc/passwdroot:x:0:0:root:/root:/bin/bashawk -F: '!($3>=500) {print $3}' /etc/passwd //找出userUID小于500的uid打印末尾是/bin/bash[root@centos7 ~]#awk -F: '$NF == "/bin/bash" {print $0}' /etc/passwdroot:x:0:0:root:/root:/bin/bashfei:x:1000:1000:fei:/home/fei:/bin/bash[root@centos7 ~]#awk -F: '$0 ~ "/bin/bash" {print $0}' /etc/passwdroot:x:0:0:root:/root:/bin/bashfei:x:1000:1000:fei:/home/fei:/bin/bash[root@centos7 ~]#awk 'BEGIN{i=0;print !i++,i}'1 1[root@centos7 ~]#awk 'BEGIN{i=0;print !(i++),i}'1 1[root@centos7 ~]#awk 'BEGIN{i=2;print !i++,i}'0 3[root@centos7 ~]#awk 'BEGIN{i=-1;print !++i,i}'1 0[root@centos7 ~]#awk 'BEGIN{i=0;print !++i,i}'0 1注意 ()不起作用函数调用:function_name(argu1, argu2, ...)条件表达式(三目表达式):selector?if-true-expression:if-false-expression示例:[root@centos7 ~]#awk -F: '{$3>=1000?usertype="Common User":usertype="SysUser";printf "%-20s|%-s\n",$1,usertype}' /etc/passwdroot |SysUserbin |SysUserdaemon |SysUser[root@centos7 ~]#awk -F: '{$3>=1000?usertype="Common User":usertype="SysUser";printf "%-20stype:%s\n",$1,usertype}' /etc/passwdroot type:SysUserbin type:SysUserdaemon type:SysUseradm type:SysUser
PATTERN:根据pattern条件,过滤匹配的行,再做处理(1) 如果未指定:空模式,匹配每一行(2) /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来awk '/^UUID/{print $1}' /etc/fstab //打印UUID的那几行awk'!/^UUID/{print $1}' /etc/fstab //不打印UUID的那几行awk '/^#/' /etc/profile //打印以#开头的awk '!/^#/' /etc/profile //不打印以#开头的(3) relational expression: 关系表达式,结果为"真"才会被处理真:结果为非0值,非空字符串假:结果为空字符串或0值示例:awk -F: 'i=1;j=1{print i,j}' /etc/passwd //每一行后加 1 1awk '!0' /etc/passwd 取反为真,打印awk '!1' /etc/passwd 取反为假,不打印awk -F: '$3>=1000{print $1,$3}' /etc/passwd uid大于1000的打印awk -F: '$3<1000{print $1,$3}' /etc/passwd uid小于1000的打印awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd 打印结尾为/bin/bash的awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd 打印结尾为bash的seq 10 | awk 'i=!i' 打印奇数行seq 10 |sed -n ''1~2pseq 10 | awk -v i=1 'i=!i' 打印偶数行seq 10 |sed -n ''2~2pseq 10|awk '!(i=!i)' 打印偶数行[root@centos7 ~]#awk 'i=!i {print NR,$0}' /etc/passwd1 root:x:0:0:root:/root:/bin/bash3 daemon:x:2:2:daemon:/sbin:/sbin/nologin5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin(4) line ranges:行范围startline,endline:/pat1/,/pat2/不支持直接给出数字格式awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd //root到nobody直接的 包括nobodyawk -F: '(NR>=1&&NR<=3){print NR,$1}' /etc/passwd //1-3行seq 10 |sed -n '2,4p'(5) BEGIN/END模式BEGIN{}: 仅在开始处理文件中的文本之前执行一次END{}:仅在文本处理完成之后执行一次
awk -F : 'BEGIN {print "USER USERID"} {print $1":"$3} END{print "end file"}' /etc/passwd //开头打印BEGIN结尾打印ENDawk -F : '{print "USER USERID";print $1":"$3} END{print "end file"}' /etc/passwd //打印USER USERID再打印$1":"$3awk -F: 'BEGIN{print " USER UID \n---------------"}{print $1,$3}' /etc/passwdawk -F: 'BEGIN{print " USER UID \n---------------"}{print $1,$3} END{print "=============="}' /etc/passwdseq 10 |awk 'i=0' 不打印seq 10 |awk 'i=1' 打印1-10seq 10 | awk 'i=!i' 打印奇数seq 10 | awk '{i=!i;print i}' 1 0 1 0seq 10 | awk '!(i=!i)' 打印偶数seq 10 |awk -v i=1 'i=!i' 打印偶数
实例:BEGIN

常用的action分类
(1) Expressions:算术,比较表达式等
(2) Control statements:if, while等
(3) Compound statements:组合语句
(4) input statements
(5) output statements:print等
{ statements;... } 组合语句if(condition) {statements;...}if(condition) {statements;...} else {statements;...}while(conditon) {statments;...}do {statements;...} while(condition)for(expr1;expr2;expr3) {statements;...}breakcontinuedelete array[index]delete arrayexit
语法:if(condition){statement;...}[else statement]if(condition1){statement1}else if(condition2){statement2}else{statement3}使用场景:对awk取得的整行或某个字段做条件判断示例:awk -F: '{if($3>=1000)print $1,$3}' /etc/passwdawk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwdawk '{if(NF>5) print $0}' /etc/fstabawk -F: '{if($3>=1000) {printf"Common user: %s\n",$1}else {printf"root or Sysuser: %s\n",$1}}' /etc/passwdawk -F: '{if($3>=1000) printf "Common user: %s\n",$1;else printf "root or Sysuser: %s\n",$1}' /etc/passwddf -h|awk -F% '/^\/dev/{print $1}'|awk '$NF>=80{print $1,$5}'df | awk '{if($0 ~ /\/dev\/sd/) print $1,$5}'awk'BEGIN{ test=100;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}'


语法:while(condition){statement;...}条件“真”,进入循环;条件“假”,退出循环使用场景:对一行内的多个字段逐一类似处理时使用对数组中的各元素逐一处理时使用示例:[root@centos7 ~]#awk -F: '{print $1,length($1)}' /etc/passwdroot 4bin 3[root@centos7 ~]#awk -F: '/^root/{i=1;while(i<NF){print $i,length($i);i++}}' /etc/passwdroot 4x 10 10 1root 4/root 5awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfgawk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10) {print $i,length($i)}; i++}}' /etc/grub2.cfgdo-while循环语法:do {statement;...}while(condition)意义:无论真假,至少执行一次循环体示例:[root@centos7 ~]#awk 'BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}'5050[root@centos7 ~]#awk -F: 'BEGIN{sum=0;for(i=1;i<=100;i++)sum+=i;print sum}'5050
语法:for(expr1;expr2;expr3) {statement;...}常见用法:for(variable assignment;condition;iterationprocess) {for-body}特殊用法:能够遍历数组中的元素语法:for(varin array) {for-body}示例:awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
[root@centos7 ~]#time for((sum=0,i=1;i<=1000000;i++));do let sum+=i;done;echo $sumreal 0m5.898suser 0m5.894ssys 0m0.000s500000500000[root@centos7 ~]#time awk -F: 'BEGIN{sum=0;for(i=1;i<=1000000;i++)sum+=i;print sum}'500000500000real 0m0.100suser 0m0.099ssys 0m0.001s[root@centos7 ~]#time seq -s+ 1000000 |bc500000500000real 0m0.381suser 0m0.374ssys 0m0.012s[root@centos7 ~]#time awk 'BEGIN{i=1;sum=0;while(i<=1000000){sum+=i;i++};print sum}'500000500000real 0m0.085suser 0m0.084ssys 0m0.001s
awk 性能最好
语法:switch(expression) {case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2; ...; default: statementn}break和continueawk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}' //偶数相加awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}' //1加到66break [n]continue [n]next:提前结束对本行处理而直接进入下一行处理(awk自身循环)awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd //偶数的uidawk -F: '{if($3%2!=1) next; print $1,$3}' /etc/passwd //奇数的uid
关联数组:array[index-expression]index-expression:(1) 可使用任意字符串;字符串要使用双引号括起来(2) 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历示例:weekdays["mon"]="Monday"awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}'awk '!arr[$0]++' dupfile详细过程awk '{!arr[$0]++;print $0, arr[$0]}' dupfile[root@centos7 ~]#cat f1aabbccccdddaadddcccc[root@centos7 ~]#awk 'arr[$0]++' f1 //重复行aadddcccc[root@centos7 ~]#awk '!arr[$0]++' f1 //不重复行(去重)aabbccccddd
若要遍历数组中的每个元素,要使用for循环for(var in array) {for-body}注意:var会遍历array的每个索引示例:awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}'netstat -tan |awk '/^tcp/{ary[$NF]++}END{for(i in ary){print i,ary[i]}}'awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_logss -nt |awk -F "[ :]" '/ESTAB/{ip[$(NF-2)]++}END{for(i in ip){print i,ip[i]}'ss -nt |awk -F "[ :]+" '/ESTAB/{ip[$(NF-2)]++}END{for(i in ip){print i,ip[i]}}'ss -nt |awk -F "[ :]+" '/ESTAB/{print $(NF-2)}'|sort|uniq -c |sort -nr|head -n10ss -nt |awk -F "[ :]+" '/ESTAB/{print $(NF-2)}'|sort|uniq -c |sort -nr|head -n10|while read count ip;do iptables -A INPUT -s $ip -j REJECT;done
数值处理:rand():返回0和1之间一个随机数awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'字符串处理:length([s]):返回指定字符串的长度sub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并将第一个匹配的内容替换为secho "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'2008-08:08 08:08:08gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容echo "2008:08:08 08:08:08" | awk 'gsub(/:/,“-",$0)'2008-08-08 08-08-08split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,...netstat -tn | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}' 外部连接ip
实例
[root@centos7]#awk 'BEGIN{v="我" ;print length(v)}'1[root@centos7]#awk 'BEGIN{srand();print rand()}' //随机数0.704931[root@centos7 wang]#awk 'BEGIN{srand();print int(rand()*100)}' //取整数52awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'//生成10个随机整数[root@centos7]# echo "11:22:33 44:55:66" | awk '{split($0,str,":")}END{for(i in str){print i,str[i]}}'4 555 661 112 223 33 44统计文件中单词的个数awk '{for(i=1;i<=NF;i++)word[$i]++}END{for(i in word)print word[i],i}' /etc/profile|sort -nr
[root@centos7 ~]#cat f1aa 100 malebb 20 malecc 50 femaledd 60 femaleee 99 xxxrr 150 ***[root@centos7 ~]#awk '{if($3=="male"){mnum++;msum+=$2}else{fnum++;fsum+=$2}}END{printf "male:%d %.2f\nfemale:%d %.2f",mnum,msum/mnum,fnum,fsum/fnum}' f1 //写死了male:2 60.00female:4 89.75[root@centos7 ~]#awk '{num[$3]++;sum[$3]+=$2}END{for(sex in num){print sex,sum[sex],sum[sex]/num[sex]}}' f1 //灵活female 110 55male 120 60*** 150 150xxx 99 99
格式:function name ( parameter, parameter, ... ) {statementsreturn expression}示例:(1)[root@centos7 ~]cat f1.txtfunction max(v1,v2) {v1>v2?var=v1:var=v2return var}BEGIN{a=3;b=2;print max(a,b)}[root@centos7 ~]#awk -f f13(2)[root@centos7 ~]cat f1.txtfunction max(v1,v2) {v1>v2?var=v1:var=v2return var}BEGIN{print max(a,b)}[root@centos7 ~]#awk -v a=3 -v b=2 -f f1.txt3(3)[root@centos7 ~]cat f1.awk#! /bin/awk -ffunction max(v1,v2) {v1>v2?var=v1:var=v2return var}BEGIN{print max(a,b)}[root@centos7 ~]#./f1.awk -v a=3 -v b=2 -f3
system命令
空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律用""引用起来。
[root@centos7 ~]#awk 'BEGIN{score=100; system("echo your score is " score) }' //打印变量 前面加空格 还有就是写到外面your score is 100[root@centos7 ~]#awk BEGIN'{system("hostname") }'centos7.qifei.com[root@centos7 ~]#ss -nt |awk -F "[ :]+" '/^ESTAB/{IP[$(NF-2)]++}END{for(i in IP){if(IP[i] >3)system("iptables -A INPUT -s "i" -j REJECT")}}' //连接数大于3加入防火墙iptables -vnL //查看禁用
将awk程序写成脚本,直接调用或执行
示例:
[root@centos7 ~]#cat f1.awk{if($3>=1000)print $1,$3}[root@centos7 ~]#awk -F: -f f1.awk /etc/passwd-----------------------[root@centos7 ~]#cat f2.awk#!/bin/awk –f#this is a awkscript{if($3>=1000)print $1,$3}[root@centos7 ~]#chmod +x f2.awk[root@centos7 ~]#f2.awk –F: /etc/passwd
格式:
awkfile var=value var2=value2... Inputfile
注意:在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通过-v参数,让awk在执行BEGIN之前得到变量的值。命令行中每一个指定的变量都需要一个-v参数
示例:
[root@centos7 ~]#cat test.awk#!/bin/awk –f{if($3 >=min && $3<=max)print $1,$3}[root@centos7 ~]#chmod +x test.awk[root@centos7 ~]#test.awk -F: min=100 max=200 /etc/passwd---------------------[root@centos7 ~]cat f1.awk#! /bin/awk -ffunction max(v1,v2) {v1>v2?var=v1:var=v2return var}BEGIN{print max(a,b)}[root@centos7 ~]#./f1.awk -v a=3 -v b=2 -f3
[root@centos7 ~]#ss -nt |awk -F "[ :]+" '/^ESTAB/{IP[$(NF-2)]++}END{for(i in IP){if(IP[i] >3)system("iptables -A INPUT -s "i" -j REJECT")}}' //连接数大于3加入防火墙iptables -vnL //查看禁用
POST --> Boot Sequence --> Bootloader --> kernel + initramfs(initrd) --> rootfs--> /sbin/initinit:CentOS 5: SysVinitCentOS 6: UpstartCentOS 7: SystemdSystemd:系统启动和服务器守护进程管理器,负责在系统启动或运行时,激活系统资源,服务器进程和其它进程Systemd新特性:系统引导时实现服务并行启动按需启动守护进程(需要那个启动那个)自动化的服务依赖关系管理(如果a依赖b会自动加载;与centos6相反)同时采用socket式与D-Bus(桌面)总线式激活服务(ip地址加端口号 ss -ntl)系统状态快照核心概念:unitunit表示不同类型的systemd对象,通过配置文件进行标识和配置;文件中主要包含了系统服务、监听socket、保存的系统快照以及其它与init相关的信息配置文件:/usr/lib/systemd/system:每个服务最主要的启动脚本设置,类似于之前的/etc/init.d/(大概与centos6 /etc/init.d/)/run/systemd/system:系统执行过程中所产生的服务脚本,比上面目录优先运行/etc/systemd/system:管理员建立的执行脚本,类似于/etc/rc.d/rcN.d/Sxx类的功能,比上面目录优先运行systemctl status httpd.service
Systemctl –t help 查看unit类型**Service unit: 文件扩展名为.service, 用于定义系统服务**Target unit: 文件扩展名为.target,用于模拟实现运行级别(简单定义下 runlevel)Device unit: .device, 用于定义内核识别的设备Mount unit: .mount, 定义文件系统挂载点**Socket unit: .socket,用于标识进程间通信用的socket文件,也可在系统启动时,延迟启动服务,实现按需启动Snapshot unit: .snapshot, 管理系统快照Swap unit: .swap, 用于标识swap设备Automount unit: .automount,文件系统的自动挂载点(ls /misc/cd)Path unit: .path,用于定义文件系统中的一个文件或目录使用,常用于当文件系统变化时,延迟激活服务,如:spool 目录没有**一般不修改[root@centos7 system]#systemctl get-default //图形的默认级别graphical.target