Shell基础之-awk命令

来源:互联网 发布:喜剧动漫 知乎 编辑:程序博客网 时间:2024/05/29 05:00

Shell基础之-awk命令

首先,大家如果看到有什么不懂的地方,欢迎吐槽!!!
我会在当天或者第二天及时回复,并且改进~~


awk编程
awk是一种编程语言。gawk、是最新版本,当前的linux版本用的都是gawk
awk是gawk的软链接

awk工作原理

   BEGIN   #在未读取文件行之前执行   主输入循环 (main input loop),反复执行,直到终止条件触发   END     #在读取文件行完毕后执行
1、在shell命令行输入命令调用awk   #awk [-f 域分隔符] 'awk cmd' file2、在awk程序段插入脚本文件,然后通过awk命令调用他   #awk -f 'awk.sh' file3、直接调用awk脚本   #./awk file

awk模式匹配

任何awk语句都由模式(pattern)和动作(action)组成    模式是一组用于测试输入行是否需要执行动作的规则(模式决定动作何时触发和触发事件)    动作是包含语句、函数和表达式的执行过程  (执行对输入行的处理)在test文件中一旦有空行,则打印出来"This is a empty line!!!"    awk '/^$/{print "This is a empty line!!!"}' test

记录和域

awk将每个输入文件行定义为记录,行中的每个字符串定义为域,分隔域的符号叫做域分隔符Li Hao  njue    025-83481010Zhang Ju    nju 025-83466534Wang Bin    seu 025-83494883Zhu Lin njupt   025-83680010按顺序打印出student文件中的2143域   awk '{print $2,$1,$4,$3}' student打印出student中所有的域   awk '{print $0}' student根据运算表达式列出第三个域的值   awk 'BEGIN {one=1;two=2}{print $(one+two)}' student以tab键位分隔符打印出student文件中第三个域   awk 'BEGIN {FS="\t"} {print $3}' student
Li Hao,njue,025-83481010Zhang Ju,nju,025-83466534Wang Bin,seu,025-83494883Zhu Lin,njupt,025-83680010以逗号为域分隔符打印出所有的域的内容   awk 'BEGIN {FS=","} {print $0}' student以逗号为域分隔符打印出13域的内容   awk 'BEGIN {FS=","} {print $1,$3}' studentabc     d   #中间两个tababc d       #中间一个tab打印出第一个域和d(两种方式)   awk 'BEGIN {FS="\t\t"} {print $1,$2}' xx   awk 'BEGIN {FS="\t"} {print $1,$3}' xx打印出第一个域和上面的d   awk 'BEGIN {FS="\t"} {print $1,$2}' xx

关系运算符

<       #小于>       #大于<=      #小于等于>=      #大于等于==      #等于!=      #不等于~      #匹配正则表达式!~     #不匹配正则表达式
在/etc/passwd文件中打印出第一个域匹配于root的内容   awk 'BEGIN {FS=":"} $1~/root/' /etc/passwd 在/etc/passwd文件中打印出全部域匹配于root的内容   awk 'BEGIN {FS=":"} $0~/root/' /etc/passwd在/etc/passwd文件中打印出全部域中不匹配nologin的内容   awk 'BEGIN {FS=":"} $0!~/nologin/' /etc/passwd在/etc/passwd文件中判断,如果UID小于GID,那么输出所有匹配的值   awk 'BEGIN {FS=":"} {if($3<$4) print $0}' /etc/passwd在/etc/passwd文件中判断,如果UID大于等于GID,那么输出所有匹配的值   awk 'BEGIN {FS=":"} {if($3>=$4) print $0}' /etc/passwd

布尔运算符

||  #逻辑或&&  #逻辑与!   #逻辑非打印出/etc/passwd文件中UID等于10或者GID等于10的行   awk 'BEGIN {FS=":"} {if($3==10||$4==10) print $0}' /etc/passwd打印出/etc/passwd文件中UID等于GID,并且登录shell都相同的匹配信息   awk 'BEGIN {FS=":"} {OFS=":"} {if($3==$4&&$7="/sbin/nologin") print $0}' /etc/passwd打印出/etc/passwd文件中UID匹配于10或GID匹配于10的匹配信息   awk 'BEGIN {FS=":"} {if($3~10||$4~10) print $0}' /etc/passwd

表达式 awk表达式用于存储、操作和获取数据,一个awk表达式可由数值,字符常量,变量,操作符,函数和正则组成

+       #加-       #减*       #乘/       #除%       #模^或**    #乘方++x #在返回x值之前,x变量加1x++ #在返回x值之后,x变量加1使用x+=1来列出文件test中的空行的行数   awk '/^$/ {print x+=1}' test第1行为0,然后递归+1列出test文件中的空行行数   awk '/^$/{print x++}' test第1行为1,然后递归+1列出test文件中的空行行数   awk '/^$/{print ++x}' test
Li     hao,njue,025-83481010,85,92,78,94,88Zhang  Ju,nju ,025-83466534,89,90,75,90,86Wang   Bin, seu,025-83494883,84,88,80,92,84Zhu    Lin,njupt,025-83680010,98,78,81,87,76求出文件student文件中学生的平均值   #awk 'BEGIN {FS=","} {total=$4+$5+$6+$7+$8} {avg=total/5} {print $1,avg}' student

系统变量:awk定义了很多内建变量用于设置环境变量信息,我们称它为系统变量,这些系统变量分为两种

   1、用于改变awk的默认值,如域分隔符   2、用于定义系统值,在处理文件时可以读取这些系统值,如记录中域数量,当前记录数,当前文件名,awk动态改变第二种系统变量的值

awk环境变量及其意义

#n          #当前记录的第n个域,域间由FS分割#0          #记录的所有域ARGC        #命令行参数的数量ARGIND      #命令行中当前文件的位置(以0开始标号)ARGV        #命令行参数的数组CONVFMT     #数字转换格式ENVIRON     #环境变量关联数组ERRNO       #最后一个系统错误的描述FILEDWIDTHS #字段宽度列表,以空格键分隔FILENAME    #当前文件名FNR         #浏览文件的记录数FS          #字段分隔符,默认是空格键IGONRECASE  #布尔变量,如果为真,则进行忽略大小写的匹配NF          #当前记录中的域数量NR          #当前记录数OFMT        #数字的输出格式OFS         #输出域分隔符,默认是空格键ORS         #输出记录分隔符,默认是换行符RLENGTH     #由match函数所匹配的字符串长度RS          #记录分隔符,默认是空格键RSTART      #由match函数所匹配的字符串的第1个位置SUBSEP      #数组下标分隔符,默认值是\034输出文件student,并在最前面加入 当前记录数,当前记录中域数量,在文件底部输出文件名   awk 'BEGIN {FS=","} {print NR,NF,$0} END {print FILENAME}' student

格式化输出 awk借鉴了C语言的语法,定义了printf输出语句,规定输出的格式

    printf (格式控制符,参数)

printf语句包含两部分

   1、格式控制符,都是以%符号开始,用以描述格式规范   2、参数列表,比如变量名列表,与格式控制符相对应,是输出的对象、

printf修饰符及其意义

    -   #左对齐width   #域的步长.prec   #小数点右边的位数

printf格式符及其意义

%c  #ASCII字符%d  #整型数%e  #浮点数,科学记数法%f  #浮点数%o  #八进制%s  #字符串%x  #十六进制数

示例:

在student中打印出字符串$2和整型数$8,并且$2之后tab,$8之后换行   awk 'BEGIN {FS=","} {printf("%s\t%d\n",$2,$8)}' student将数字65转换为ASCII码   awk 'BEGIN {printf("%c\n",65)}'将2014转换为浮点数,默认小数位六位   awk 'BEGIN {printf("%f\n",2014)}'打印出student文件中的第一个域和第三个域,并且第一个域的字符串和第三个域的字符串相差15个空格      awk 'BEGIN {FS=","} {printf("%-15s\t%s\n",$1,$3)}' student打印出student文件中的第一个域和第三个域,并且在行首加入第一个域的注释Name,第三个域的注释Phonenumber   awk 'BEGIN {FS=",";print "Name\t\tPhonenumber"} {printf("%-16s%s\n",$1,$3)}' student 打印出浮点数控制在10为,小数点后保留三位的数   awk 'BEGIN {printf("%10.3f\n",20141126)}'  #如果数不满10位,则会按空格补齐   2011111.000  满10位     201.000      不满10位

内置字符串函数 awk提供了强大的内置字符串函数,用于实现文本的字符串替换、查找以及分隔等功能

awk字符串函数及其意义

gsub(r,s)       #在输入文件中用s替换rgsub(r,s,t)     #在t中用s替换rindex(s,t)      #返回s中字符串第一个t的位置length(s)       #返回s的长度match(s,t)      #测试s是否包含匹配t的字符串split(r,s,t)    #在t上将r分成序列ssub(r,t,s)      #将t中第1次出现的r替换为ssubstr(r,s)     #返回字符串r中从s开始的后缀部分substr(r,s,t)   #返回字符串r中从s开始长度为t的后缀部分

示例:

在passwd中把第一个域的root替换为"My name is root",并输出为:格式打印出来   awk 'BEGIN {FS=":";OFS=":"} gsub(/root/,"my name is root",$1) {print $0}' /etc/passwd 在passwd中把所有域的root替换为"My name is root",并输出为:格式打印出来打印出abcdefg字符串中f出现的首位置   awk 'BEGIN {print index("abcdefg","f")}'打印出"This is a httpd server script"这串字符串的长度   awk 'BEGIN {print length("This is a httpd server script")}'测试"This is a httpd server script!!!"这串字符串中!的首位置   awk 'BEGIN {print match("This is a httpd server sctipt!!!","!")}'测试"This is a httpd server sctipt!!!"这串字符串中C的首位置(忽略大小写)   awk 'BEGIN {IGNORECASE=1;print match("This is a httpd server sctipt!!!",/C/)}'将字符串"This script is a httpd server script!!!"中第一个出现的sctipt替换为SCRIPT   awk 'BEGIN {file="This script is a httpd server script!!!";sub(/script/,"SCRIPT",file);printf("%s\n",file)}'将student文本中第一个域匹配Li行中的第一个出现的10替换为99   awk 'BEGIN {FS=","} {$1~Li sub(/10/,"99",$0);print $0}' student返回file文件中从第5个字符开始的后缀部分 file="This script is a httpd server script!!!"   awk 'BEGIN {file="This script is a httpd server script!!!";print substr(file,6)}'返回file文件中从第6个字符开始长度为9的后缀部分   awk 'BEGIN {file="This script is a httpd server script!!!";print substr(file,6,9)}'在student文件记录首部插入记录行号和域数,并且使用分隔符.进行分隔打印   awk 'BEGIN {FS=","} {print NR,NF,$0}' OFS="." student            
0 0
原创粉丝点击