cf2000 发表于 2018-8-17 08:30:29

【一天一个shell命令】文本内容操作系列-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 -f 脚本文件 [--] 文件 ...
  
用法: awk [--] '程序' 文件 ...
  
POSIX 选项:             GNU 长选项:
  
    -f 脚本文件      --file=脚本文件
  
    -F fs            --field-separator=fs
  
指定输入文本分隔符,fs是一个字符串或者是一个正则表达式,
  
    -v var=val      --assign=var=val
  
将外部变量值付给var
  
    -m val
  
    -O            --optimize
  
启用一些优化程序的内部表示。
  
    -W compat      --compat
  
在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
  
    -W copyleft      --copyleft
  
打印简短的版权信息
  
    -W copyright      --copyright
  
打印短版的通用公共许可证,然后退出
  
    -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做个比较全面的认识。


页: [1]
查看完整版本: 【一天一个shell命令】文本内容操作系列-awk