一天一个shell命令 linux文本内容操作系列-awk命令详解
简介
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本:awk、nawk和gawk,未作特别说明,一般指gawk,gawk是AWK的GNU版本。
awk其名称得自于它的创始人AlfredAho、PeterWeinberger和BrianKernighan姓氏的首个字母。实际上AWK的确拥有自己的语言:AWK程序设计语言,三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。
使用方法
awk'{pattern+action}'{filenames}
尽管操作可能会很复杂,但语法总是这样,其中pattern表示AWK在数据中查找的内容,而action是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。
调用awk
有三种方式调用awk
说明:
awk被设计用于数据流,能够对列和行进行操作。而sed更多的是匹配,进行替换和删除。
awk有很多内建的功能,比如数组,函数等。灵活性是awk的最大优势。
awk的结构
awk'
BEGIN{print"start"}
pattern{commands}
END{print"end"}'
file
为了偏于观看,我打了回车,实际上是一行
一个awk脚本通常是3部分
1.BEGIN语句块
2.能够使用模式匹配的通用语句块
3.END语句块
他们任何一部分都可以不出现在脚本中。脚本通常包含在双引号或者单引号内。
例如:
awk'BEGIN{i=0}{i++}END{printi}'filename
工作原理
awk命令的工作方式如下:
1.执行BEGIN{commands}语句块中的语句
2.从文件或者stdin中读取一行,然后执行pattern{commands}.迭代直到全部读取完毕
3.最后执行END{commands}语句块
再次提醒,他们任何一部都可以没有
而awk的功能也远不止如此
入门实例:
echo|awk'{var1="v1";var2="v2";var3="v3";printvar1,var2,var3;}' 打印:v1v2v3
解释:逗号为定界符(分隔符)
echo|awk'{var1="v1";var2="v2";var3="v3";printvar1"-"var2"-"var3;}'
打印v1-v2-v3
解释:双引号为连接符
其他任何符号,都不能正常输出v1,v2,v3
解读--help(一个非常庞大复杂的帮助文档,官方用了410页的篇幅PDF来介绍,如果我只言片语,你信我自己都不信。。)
用法:awk[POSIX或GNU风格选项]-f脚本文件[--]文件...
用法:awk[POSIX或GNU风格选项][--]'程序'文件...
POSIX选项: GNU长选项:
-f脚本文件 --file=脚本文件
-Ffs --field-separator=fs
指定输入文本分隔符,fs是一个字符串或者是一个正则表达式,
-vvar=val --assign=var=val
将外部变量值付给var
-m[fr]val
-O --optimize
启用一些优化程序的内部表示。
-Wcompat --compat
在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
-Wcopyleft --copyleft
打印简短的版权信息
-Wcopyright --copyright
打印短版的通用公共许可证,然后退出
-Wdump-variables[=file] --dump-variables[=file]
打印全局变量,其类型,提交的最终值的排序列表。
-Wexec=file --exec=file
与-f类似,但与他有两点不同,(我回头把相关文档上传,太长)
-Wgen-po --gen-po
(内容太多)
-Whelp --help打印帮助
-Wlint[=fatal] --lint[=fatal]
警告可疑或不移植到其他的awk实现的结构
-Wlint-old --lint-old
打印关于不能向传统unix平台移植的结构的警告
-Wnon-decimal-data --non-decimal-data
启用自动输入数据的解释,八进制和十六进制值
-Wprofile[=file] --profile[=file]
启用awk程序剖析
-Wposix --posix
在严格意义上的POSIX模式运作。
-Wre-interval --re-interval
允许间隔表达式在正则表达式上
-Wsource=program-text --source=program-text
-Wtraditional --traditional
传统的Unixawk的正则表达式匹配
-Wusage --usage
-Wuse-lc-numeric --use-lc-numeric
解析数字输入时,强制使用的语言环境中的小数点字符
数据
-Wversion --version
提交错误报告请参考“gawk.info”中的“Bugs”页,它位于打印版本中的“Reporting
ProblemsandBugs”一节
注意:gawk是awk的GNU版本,即使help,在ubuntu下也需要先安装gawk
这回我们就不解读了,为了增加大家的信息和乐趣,先来点基本的:
部分特殊变量:
NR:表示记录数量,在执行过程中对应于行号
NF:表示字段数量,在执行过程中对应于当前行的字段数
$0:这个变量包含执行过程中当前行的文本内容
$1:第一个字段的文本内容
$2:第二个字段的文本内容
例子:
例1.
echo-e"line1f2f3\nline2f4f5\nline3f6f7"|\#这个\是在窗口中写多行命令用的 awk'{ print"Lineno:"NR",Nooffields:"NF,"$0="$0,"$1="$1,"$2="$2,"$3="$3 }'
小注一下:$1是打印第一个,$NF打印最后一个字段,$(NF-1)打印倒数第二个
例2.
seq5|awk'BEGIN{sum=0;print"Summation:"}{print$1"+";sum+=1}END{print"==";printsum}'
这个例子用到了基本格式。
BEGIN中初始化了sum,打印Summation
中间模块打印了第一列,然后给sum+1
END中打印了sum
例3.关于-v外部变量
$VAR=10000 $echo|awk–vVARIABLE=$VAR'{printVARABLE}'
还有另一种灵活的方法可以将多个外部变量传递给awk,例如:
$var1="value1"var2="value2" $echo|awk'{printv1,v2}'v1=$var1v2=$var2
如果来自文件
awk'{printv1,v2}'v1=$var1v2=$var2filename
例4
$awk'NR<5'#行号小于5
$awk'NR==1,NR==4'#行号在1到5之间的行
$awk'/linux/'#包含样式linux的行(可以用正则表达式指定样式)
$awk'!/linux/'#不包含样式linux的行
这次先写这些,争取在花2个篇幅能把awk做个比较全面的认识。
awk补充
之前我们学习了awk基本入门,我惊喜的发现有awk一篇详细文章,有写念头,不能全部转载,转化成自己的方式来写一些。
主讲内置变量和部分字符串函数
内置变量(有翻译特殊变量和环境变量,按照官方翻译为内置变量)
SUBSEP 数组下标分隔符(默认值是\034)。
蓝色为新增加的内置变量。
简单举例:
1.
01.sed1q/etc/passwd|awk'{FS=":";print$1}'
打印密码第一行,用冒号分隔符
2.
awk'END{printFILENAME}'awk.txt
打印文本FILENAME
3.seq100|awk'NR==4,NR==6'
打印4到6行
再介绍几个awk内置的字符串函数,也讲一部分。
length(string):
返回字符串的长度
index(string,serch_string):
返回search_string在字符串中出现的位置
split(string,array,delimiter):
用定界符生成一个字符串列表,并将该列表存入数组
substr(string,array,delimiter):
在字符串中用字符起止便宜量生成子串,并返回该子串
sub(regex,replacement_str,string):
将正则表达式匹配到的第一处内容替换成replacement_str
gsub(regex,replacement_str,string):
和sub()类似。不过该函数会替换正则表达式匹配到的所有内容
match(regex,string):
检查正则表达式是否能够匹配字符串。如果能够匹配,返回非0值;否则,返回0.match()有两个相关的特殊变量,分别是RSTART喝RLENGTH。变量RSTART包含正则表达式所匹配内容的其实位置,而变量RLENGTH包含正则表达式所匹配内容的长度。
举例:
1.$awk'{sub(/test/,"mytest");print}'testfile
在整个记录中匹配,替换只发生在第一次匹配发生的时候
2.$awk'{sub(/test/,"mytest");$1};print}'testfile
在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候
3.$awk'{printindex("test","mytest")}'testfile
实例返回test在mytest的位置,结果应该是3
4.$awk'{printlength("test")}'
实例返回test字符串的长度。
awk补充二
这节可能要写的比较粗了,时间太少。
一.内置函数
注意一种约定俗称语法习惯:[a]代表a可选.
数字函数(NumericFunctions)
函数名 说明
atan2(y,x)
返回y/x弧的反正切
cos(x)
返回x的余弦
exp(x)
返回x的指数
int(x)
返回最靠近的整数,风向标指向0
log(x)
返回x的自然对数
rand()
返回随机数
sin(x)
返回x的正弦
sqrt(x)
返回x的正平方根
srand([x])
生成随机数,可以设置起点
字符串操作函数(String-ManipulationFunctions)
注意:蓝色部分为gawk特有,awk没有此函数功能。
输入输出函数(Input/OutputFunctions)
时间函数(TimeFunctions)
位操作函数(Bit-ManipulationFunctions)
获取类型信息(GettingTypeInformation)
字符串转换函数(String-TranslationFunctions)
返回string1和string2的翻译数量的复数形式,string1,string2在语言环境类别的文本域里
内置函数还有些高级特性,等许多实例,以后有机会补充。
二.自定义函数
格式入下:
functionname([parameter-list]) { body-of-function }
如:
functionmyprint(num) { printf"%6.3g\n",num }
awk这个命令还有很多功能,打算就只写这么多了。以后可能更多在一些例子里,与其他命令结合时会提到。