""" note: txt文档通用说明 '#!' - 主标题 '##' - 子标题 '-/-' - 子事项 '---' - 事项说明 '-1-' - 详细事项 '# 1.' - 要点事项说明 'note:' - 注意事项 """ note: :参考链接:https://blog.csdn.net/ljlfather/article/details/104530474/ #!awk常用总结信息 ## awk的命令格式 --- awk 'pattern {atcion}' filename --- awk '{pattern + action}' filename --- awk [ -F 分隔符] [ -v 变量名=值 ] 'BEGIN{语句} 条件类型1{动作1} 条件类型2{动作2}... END{语句}' 输入的文件 -/- 命令格式说明 -1- awk命令格式由四部分组成;选项,BEGIN,END和带条件类型和动作的语句;这四个部分都是可选项,可省略任意部分; -2- -F表示设置列分隔符,默认为空格; -3- -v 表示初始化一个变量或者用于向awk命令传入外部变量值,shell编程中常用; -4- 条件类型可以是正则表达式,条件语句,复合语句以及行匹配范围等内容;条件类型为可选设置;如果设置条件,只处理匹配条件的行执行动作;如果未设置,awk命令则认为所有行都是匹配的,并执行动作语句;动作表示执行的命令,命令必须放在大括号{}内; -5- 必须了解这些符号;$0表示行,$1,$2,$3...$n分别表示第1列,第2列,第3列...第n列;awk命令经常会使用这些符号去做匹配,打印指定指定列等操作; -/- awk命令处理流程 -1- 执行BEGIN{}语句块中的内容;BEGIN语句通常用户变量初始化、打印输出表格的表头; -2- 从文件或者stdin中读取一行;然后根据条件类型的匹配关系,判断是否需要执行后面的动作;直到做完所有的动作和条件类型;重复这个过程,直到文件所有行处理完成; -3- 执行END语句块中的内容;END语句块常用于分析汇总等统计信息,比如统计文件行数; ## awk常用参数 --- -f: 后面加指定的awk脚本文件名; --- -F: 后面加分隔符;以什么字符作为一行数据的分隔符;默认为空格 --- -v: 增加变量 ## awk使用特殊符 --- 正则表达式匹配条件匹配操作符: . * + ? $ | \ [] {} ( --- 条件操作符: <(小于) <=(小于等于) ==(等于) >(大于) >=(大于等于) !=(不等于) ~(匹配正则表达式) !~(不匹配正则表达式) --- 算数运算符: +(加) -(减) *(乘) /(除) %(取余) ++(增加1) --(减1) ^n(次方) --- 逻辑运算符: && || ! ## awk命令pattern匹配规则 -/- /正则表达式/: 使用通配符的扩展集 -1- 匹配包含template1的行 --- awk '/template1/{action}' filename -2- 匹配不包含template1且不包含template2的行 --- awk '$0 !~ /template1/ && $0 !~ /template2/{atcion}' filename -3- 匹配包含template1且第一个域包含template2的行 --- awk '$0 ~ /template1/ && $1 ~ /template2/{atcion}' filename -4- 匹配template1开头的行 --- awk '$0 ~ /^template1/{atcion}' filename -5- 匹配包含template1或者包含template2的行 --- awk '$0 !~ /template1/ || $0 !~ /template2/{atcion}' filename -6- 匹配第一个包含template1到第一个template2之间的行 --- awk '/template1/,/template2/{action}' filename note: --- ','在两个相连的表达式之间表示的是一个范围 -/- 条件表达式: 使用运算操作符比较测试 -1- 第一个域等于template1的行 --- awk '{if($1 == "template1")atcion}' filename -2- 第二个域小于500的行 --- awk '{if($2 < 500)atcion}' filename -3- 输出小于100的数 --- awk 'BEGIN{for(i=0;i<100;i++)print i}' -/- 匹配表达式: 使用~或者!~匹配 -1- 匹配不包含template1且不包含template2的行 --- awk '$0 !~ /template1/ && $0 !~ /template2/{atcion}' filename -/- GEBIN/pattern/END语句块 -1- 输出表头信息,表内容并统计行 --- awk 'BEGIN{print "This is test"}{print }END{print NR}' filename ## awk外部变量引用 -/- awk使用-v参数 --- grep -A 12 '#template_3' template.txt | egrep '^[0-9]+' | awk -v a=value1 -v b=${value2} '{if( $23==a && $24==b )print $4,$5}' -/- awk使用单引号引用外部变量 --- a=value1 --- b=value2 --- grep -A 12 '#template_3' template.txt | egrep '^[0-9]+' | awk '{if($23=="'"$a"'" && $24=="'"$b"'")print $4,$5}' ## awk内置变量 -/- awk的内置变量包括FS,NF,OFS,ORS,NR,FILENAME等内容 --- ARGC: 命令行参数个数 --- ARGV: 命令行参数排列 --- ENVIRON: 支持队列中系统环境变量的使用 --- FILENAME: awk浏览的文件名 --- FNR: 浏览文件的记录数 --- FS: 设置输入域分隔符,等价于命令行 -F选项{预定义信息,适用于BEGIN块} --- NF: 浏览记录的域的个数 --- $NF: 每行中最后一个字段 --- $(NF-1): 每行中的倒数第二个字段,以此类推$(NF-2)为倒数第三,同理NF,NR均可相同用法 --- NR: 已读的记录数 --- FNR: 用法同NR一样,不过是用来处理多个文件(行数会根据文件读取排序来区分排序) --- OFS: 输出域分隔符 --- ORS: 输出记录分隔符 --- RS: 控制记录分隔符 --- $0: 整条记录,所有域 --- $1: 第一个域($2..$n以此类推) note: -1- FS和OFS --- 需要搭配BEGIN{commands}语句块使用,FS相当于-F参数,当FS与OFS在一起使用的时候,需要用 ';'(分号)隔开;注意当你的数据字段变量为$0的时候,OFS不生效 ## awk内置算术函数 -/- int(x): 取整数部份,朝0的方向做舍去 -/- sqrt(x): 正的平方根 -/- exp(x): 以e为底的指数函数 -/- log(x): 自然对数 -/- sin(x): 正弦 -/- cos(x): 余弦 -/- atan2(y,x): 求y/x 的arctan值,单位是弧度 -/- rand(): 得到一个随机数(平均分布在0和1之间) -/- srand(x): 设定产生随机数的seed为x note: --- 预定义值,适用于BEGIN块 --- awk 'BEGIN{i=3.1415926;print int(i)}' --- awk 'BEGIN{rand();num=rand();print num}' ## awk内置字符串函数 -/- index(str,substr): 返回子串substr在字符串str中第一次出现的位置,若找不到,则返回值为0; -/- length(str): 返回字符串str 的字符个数; -/- match(str,rexp): 返回模式rexp 在字符串str中第一次出现的位置,如果str中不包含rexp,则返回值0; -/- sprintf(format,exp1,...): 返回一个指定格式的表达式,格式format与printf的打印格式类似;(不在屏幕上输出) -/- sub(rexp,sub_str,target): 在目标串target中寻找第一个能够匹配正则表达式rexp的子串,并用字符串sub_str替换该子串;若没有指定目标串,则在整个记录中查找; --- awk 'BEGIN{str="water,water";sub(/at/,"ith",str);print str}' -/- gsub(rexp,sub_str,target): 与sub 类似,但gsub替换所有匹配的子串,即全局替换; -/- substr(str,start,len): 返回str的从指定位置start开始长度为len个字符的子串,如果len省略,则返回从start位置开始至结束位置的所有字符; --- awk 'BEGIN{print substr("awk sed grep",5)}' -/- split(str,array,fs): 使用由fs指定的分隔符将字符串 --- str拆分成一个数组array,并返回数组的下标数; --- awk 'BEGIN{split("11/15/2005",date,"/"); print date[2]}' -/- tolower(str): 将字符串str中的大写字母改为小写字母; --- awk 'BEGIN{print tolower("MiXeD CaSe 123")}' -/- toupper(str): 将字符串str中的小写字母改为大写字母; -/- close(filename): 将输入或输出的文件filename 关闭; -/- system(command): 此函数允许调用操作系统的指令,执行完毕後将回到awk 程序; --- awk 'BEGIN {system("ls")}' ## awk使用if判断 -/- 单if使用,第一个字段内容等于"root"就显示 --- awk -F":" '{if($1=="root")print$0}' /etc/passwd -/- 另一种写法,和上面一样,不用带if 用()就可以了 --- awk -F":" '($1=="root"){print$0}' /etc/passwd -/- 单if使用,第一个字段等于"root"就跳过,显示后面的,和上面正好显示相反的 --- next 本次直接跳过,exit直接退出,但是有EOF还是要执行EOF的内容 --- awk -F":" '{if($1=="root")next}{print$0}' /etc/passwd -/- and的用法,表示显示第2到10行数据 --- awk -F: '{if(NR>=2&&NR<=10)print $1}' /etc/passwd -/- or的用法,表示显示第2和第10行 --- awk -F: '{if(NR==2||NR==10)print $1}' /etc/passwd -/- 取反的用法,除了第二行,其他都显示 --- awk -F: '{if(NR!=2)print $1}' /etc/passwd -/- 双分支使用,以ID号为参数,大于500的输出为系统用户,其他输出为普通用户 --- awk -F: '{if($3<=500){print$1,$3,"系统用户"}else{print$1,$3,"普通用户"}}' /etc/passwd ## awk循环 -/- for循环 --- for循环有两种语法格式: -1- for(初始化;布尔表达式;表达式){语句…} --- awk 'BEGIN{for(i=0;i<10;i++)print i}' -1- for(变量 in 数组){语句…} --- awk 'BEGIN{list[1]=1;list[2]=2;list[3]=3;for(i in list)print list[i]}' -/- while循环 --- while(布尔表达式){语句…} --- awk 'BEGIN{i=0;while(i<10){print i;i++};exit}' -/- do-while循环 --- do {代码语句…}while(条件) --- awk 'BEGIN{i=0;do{print i;i++}while(i<10)}' note: 循环控制 --- exit: 退出整个块命令行 --- next: 结束当前块命令指令结果,当前循环或者当前块后续命令不执行 --- continue: 跳出当前循环 --- break: 跳出整个循环 --- nextfile: 满足某个条件后,跳过当前正在操作的文件 ## awk数组 --- 分类计算,用于统计 --- awk 'BEGIN{arr[0]="a1";arr[1]="a2";arr[2]="a3";for(i in arr)print i,arr[i]}'