1 作为Linux系统管理员的瑞士小军刀,awk的作用是显而易见的,但是一般情况下使用的都是很简单的分割打印,但有时候需要稍微复杂一些的用法,这里进行一下我的总结。其实之前有写过一篇awk的博客,不过写的比较基础,这次作为补充并尽可能覆盖常用用法,之前的地址戳这里

感受一下

通过一个简单的实例来进行说明,实例数据如下,其他介绍放在后面,毕竟实例比理论来的直观嘛:

NumID Name Math English Chinese
M5 Arvon 13 14 15
F3 Mo 92 02 26
F4 Pikachu 52 10 11
M1 Steavn 1 2 3
F2 World 4 5 56

鲜活的小栗子

  • 基础1:获取姓名和英语成绩
    1
    
    awk -F' ' '{print $2,$4}' xxx.txt
    
  • 基础2:设置输入和输出分隔符的姓名和成绩
    1
    
    awk 'BEGIN{FS=" ";OFS="---"}{print $2,$4}' xxx.txt
    
  • 基础3: 输出行号列数带描述的姓名和成绩
    1
    
    awk 'BEGIN{FS=" ";OFS="---"}{print "filename:" FILENAME, "lineNum:"NR, "leishu:"NF, $2,$4}' xxx.txt
    
  • 基础4:添加Title和结束符并设置输入输出分隔符的例子
    1
    
    awk 'BEGIN{print "T1","T2","T3","T4"}{FS=" ";OFS="---"}{print "filename:" FILENAME, "lineNum:"NR, "leishu:"NF, $2,$4}END{print "Game Over"}' xxx.txt
    
  • 基础5: 带匹配的,例如匹配Arvon并输出成绩
    1
    2
    3
    
    awk 'BEGIN{FS=" "}/Arvon/{print $0}' xxx.txt
    awk 'BEGIN{FS=" "}/M[1-9]/{print $0}' xxx.txt
    awk 'BEGIN{FS=" "}/M./{print $0}' xxx.txt
    

嗨嗨的大栗子

**说明一下:**awk的条件是从C语言借鉴而来,反正C我也不会,但awk应该会,关于AWK变成的资料极多,我这里就写一些常用简单的啦~ **还有还有–>awk工作流程:**先执行BEGIN,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。

  • 高阶1:行计数累加,获取每个人的成绩总和
    1
    
    awk 'BEGIN{FS=" "}/M[1-9]|F[1-9]/{print $0,$3+$4+$5}' xxx.txt
    
  • 高阶2:列累加,获取所有人每科成绩的总和
    1
    
    awk 'BEGIN{FS=" "}/F[1-9]|M[1-9]/{sMath=sMath+$3;sEnglish=sEnglish+$4;sChinese=sChinese+$5}END{print sMath,sEnglish,sChinese}' xxx.txt
    
  • 高阶3:数据筛选计数,获取数学成绩大于10的人数,并列出是谁
    1
    
    awk 'BEGIN{renshu=0}{FS=" "}/F[1-9]|M[1-9]/{if ($3>10) {print $0; renshu+=1}}END{print "totleNum:" renshu}' xxx.txt
    
  • 高阶5:带过滤筛选的求和,求英语成绩大于等于5的人的各科成绩总和
    1
    
    awk 'BEGIN{sMath=0;sEng=0;sChi=0}/F[1-9]|M[1-9]/{if($4>=5){print $0;sMath+=$3;sEng+=$4;sChi+=$5}}END{print "sMath:" sMath, "sEng:" sEng, "sChi:" sChi}' xxx.txt
    

名词解释

  • 内建变量
  • Record(记录):awk从数据文件上读取数据的基本单位,默认内建变量RS为换行 如:例子中的“M5 Arvon 13 14 15”就是一条记录
  • Field(字段):记录中被分隔开的子字符串,默认内建变量FS为空格 如:例子中第一条记录的第一个字符串为M5,第二个为Arvon

内建变量

变量名称 描述
$n 当前记录的第n个字段,字段间由FS分隔
$0 完整的输入记录
ARGC 命令行参数的数目
ARGIND 命令行中当前文件的位置(从0开始算)
ARGV 包含命令行参数的数组
CONVFMT 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO 最后一个系统错误的描述
FIELDWIDTHS 字段宽度列表(用空格键分隔)
FILENAME 当前文件名
FNR 各文件分别计数的行号
FS 字段分隔符(默认是任何空格)
IGNORECASE 如果为真,则进行忽略大小写的匹配
NF 输入字段分割符
NR 已经读出的记录数,就是行号,从1开始
OFMT 数字的输出格式(默认值是%.6g)
OFS 输出记录分隔符(输出换行符),输出时用指定的符号代替换行符
ORS 输出记录分隔符(默认值是一个换行符)
RLENGTH 由match函数所匹配的字符串的长度
RS 记录分隔符(默认是一个换行符)
RSTART 由match函数所匹配的字符串的第一个位置
SUBSEP 数组下标分隔符(默认值是/034)

以上,还有很多用法暂时就先这样吧,有了再补充,awk编程也是厉害了