⼀天⼀个shell命令linux⽂本内容操作系列-awk命令详解简介
awk是⼀个强⼤的⽂本分析⼯具,相对于grep的查,sed的编辑,awk在其对数据分析并⽣成报告时,显得尤为强⼤。简单来说awk就是把⽂件逐⾏的读⼊,以空格为默认分隔符将每⾏切⽚,切开的部分再进⾏各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,⼀般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名称得⾃于它的创始⼈ Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓⽒的⾸个字母。实际上 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{print i}' filename
⼯作原理
awk命令的⼯作⽅式如下:
1. 执⾏BEGIN{commands}语句块中的语句
2. 从⽂件或者stdin中读取⼀⾏,然后执⾏pattern{commands}. 迭代直到全部读取完毕
3. 最后执⾏END{commands}语句块
再次提醒,他们任何⼀部都可以没有
⽽awk的功能也远不⽌如此
⼊门实例:
复制代码代码如下:
echo | awk '{var1="v1";var2="v2";var3="v3"; print var1,var2,var3;}'
打印: v1 v2 v3
解释:逗号为定界符(分隔符)
echo | awk '{var1="v1";var2="v2";var3="v3"; print var1"-"var2"-"var3;}'
打印v1-v2-v3
解释:双引号为连接符
其他任何符号,都不能正常输出v1,v2,v3
解读--help(⼀个⾮常庞⼤复杂的帮助⽂档,官⽅⽤了410页的篇幅PDF来介绍,如果我只⾔⽚语,你信我⾃⼰都不信。。)
⽤法: awk [POSIX 或 GNU 风格选项] -f 脚本⽂件 [--] ⽂件 ...
⽤法: awk [POSIX 或 GNU 风格选项] [--] '程序' ⽂件 ...
POSIX 选项: GNU 长选项:
-f 脚本⽂件 --file=脚本⽂件
-F fs --field-separator=fs
指定输⼊⽂本分隔符,fs是⼀个字符串或者是⼀个正则表达式,
-v var=val --assign=var=val
将外部变量值付给var
-m[fr] val
-O --optimize
启⽤⼀些优化程序的内部表⽰。
-W compat --compat
在兼容模式下运⾏awk。所以gawk的⾏为和标准的awk完全⼀样,所有的awk扩展都被忽略。
-W copyleft --copyleft
打印简短的版权信息
-W copyright --copyright
shell代码
打印短版的通⽤公共许可证,然后退出
-W dump-variables[=file] --dump-variables[=file]
打印全局变量,其类型,提交的最终值的排序列表。
-W exec=file --exec=file
与-f类似,但与他有两点不同,(我回头把相关⽂档上传,太长)
-W gen-po --gen-po
(内容太多)
-W help --help 打印帮助
-W lint[=fatal] --lint[=fatal]
警告可疑或不移植到其他的awk实现的结构
-W lint-old --lint-old
打印关于不能向传统unix平台移植的结构的警告
-W non-decimal-data --non-decimal-data
启⽤⾃动输⼊数据的解释,⼋进制和⼗六进制值
-W profile[=file] --profile[=file]
启⽤awk程序剖析
-W posix --posix
在严格意义上的POSIX模式运作。
-W re-interval --re-interval
允许间隔表达式在正则表达式上
-W source=program-text --source=program-text
-W traditional --traditional
传统的Unix awk的正则表达式匹配
-W usage --usage
-W use-lc-numeric --use-lc-numeric
解析数字输⼊时,强制使⽤的语⾔环境中的⼩数点字符
数据
-W version --version
提交错误报告请参考“gawk.info”中的“Bugs”页,它位于打印版本中的“Reporting
Problems and Bugs”⼀节
注意:gawk是awk的GNU版本,即使help ,在ubuntu下也需要先安装gawk
这回我们就不解读了,为了增加⼤家的信息和乐趣,先来点基本的:
部分特殊变量:
NR: 表⽰记录数量,在执⾏过程中对应于⾏号
NF:表⽰字段数量,在执⾏过程中对应于当前⾏的字段数
$0: 这个变量包含执⾏过程中当前⾏的⽂本内容
$1: 第⼀个字段的⽂本内容
$2: 第⼆个字段的⽂本内容
例⼦:
例1.
复制代码代码如下:
echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7"|\#这个\是在窗⼝中写多⾏命令⽤的
awk '{
print "Line no:"NR",No of fields:"NF, "$0="$0,"$1="$1,"$2="$2,"$3="$3
}'
⼩注⼀下:$1是打印第⼀个,$NF打印最后⼀个字段,$(NF-1)打印倒数第⼆个
例2.
seq 5 | awk 'BEGIN{ sum=0;print "Summation:"}{print $1"+";sum+=1}END{print "==";print sum}'
这个例⼦⽤到了基本格式。
BEGIN中初始化了sum,打印Summation
中间模块打印了第⼀列,然后给sum+1
END中打印了sum
例3. 关于-v 外部变量
复制代码代码如下:
$ VAR=10000
$echo | awk –v VARIABLE=$VAR'{print VARABLE}'
还有另⼀种灵活的⽅法可以将多个外部变量传递给awk,例如:
复制代码代码如下:
$var1="value1" var2="value2"
$echo | awk '{print v1,v2}' v1=$var1 v2=$var2
如果来⾃⽂件
awk '{print v1,v2}' v1=$var1 v2=$var2 filename
例4
$awk 'NR < 5' #⾏号⼩于5
$awk 'NR==1,NR==4' #⾏号在1到5之间的⾏
$awk '/linux/' #包含样式linux的⾏(可以⽤正则表达式指定样式)
$awk '!/linux/' #不包含样式linux的⾏
这次先写这些,争取在花2个篇幅能把awk做个⽐较全⾯的认识。
awk补充
之前我们学习了awk基本⼊门,我惊喜的发现有awk⼀篇详细⽂章,有写念头,不能全部转载,转化成⾃⼰的⽅式来写⼀些。主讲内置变量和部分字符串函数
内置变量(有翻译特殊变量和环境变量,按照官⽅翻译为内置变量)
变量说明
$n当前记录的第n个字段,字段间由FS分隔。
$0完整的输⼊记录。
ARGC命令⾏参数的数⽬。
ARGIND命令⾏中当前⽂件的位置(从0开始算)。
ARGV包含命令⾏参数的数组。
BINMODE在⾮POSIX系统上,这个变量指定的所有I / O使⽤⼆进制模式
CONVFMT数字转换格式(默认值为%.6g)
ENVIRON环境变量关联数组。
ERRNO最后⼀个系统错误的描述。
FIELDWIDTHS字段宽度列表(⽤空格键分隔)。
FILENAME当前⽂件名。
FNR同NR,但相对于当前⽂件
FPAT这是⼀个正则表达式(字符串),告诉gawk基于匹配正则表达式的⽂本来创建字段FS字段分隔符(默认是任何空格)。
IGNORECASE如果为真,则进⾏忽略⼤⼩写的匹配。
LINT当这个变量为真(⾮零或⾮空),gawk的⾏为犹如"--lint"命令⾏选项
NF当前记录中的字段数。
NR当前记录数。
OFMT数字的输出格式(默认值是%.6g)。
OFS输出字段分隔符(默认值是⼀个空格)。
ORS输出记录分隔符(默认值是⼀个换⾏符)。
PROCINFO这个数组的元素提供访问运⾏awk程序的信息
RLENGTH由match函数所匹配的字符串的长度。
RS记录分隔符(默认是⼀个换⾏符)。
RT每次⼀条记录被读取的设置
RSTART由match函数所匹配的字符串的第⼀个位置。
SUBSEP数组下标分隔符(默认值是\034)。
TEXTDOMAIN此变量⽤于程序的国际化
蓝⾊为新增加的内置变量。
简单举例:
1.
01.sed 1q /etc/passwd | awk '{ FS = ":"; print $1 }'
打印密码第⼀⾏,⽤冒号分隔符
2.
复制代码代码如下:
awk 'END{print FILENAME}'
打印⽂本FILENAME
3. seq 100 | 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 '{ print index("test", "mytest") }' testfile
实例返回test在mytest的位置,结果应该是3
4.$ awk '{ print length( "test" ) }'
实例返回test字符串的长度。
awk补充⼆
这节可能要写的⽐较粗了,时间太少。
⼀. 内置函数
注意⼀种约定俗称语法习惯: [a]代表a可选.
数字函数(Numeric Functions)
函数名说明
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-Manipulation Functions)
注意:蓝⾊部分为gawk特有,awk没有此函数功能。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论