三十分钟学会awk(一)

来源:互联网 发布:部落冲突蛮王升级数据 编辑:程序博客网 时间:2024/04/30 19:52

AWK的典型应用
1、文本处理
2、输出格式化的文本报表
3、执行算数运算
4、执行字符串操作等
工作流
要成为AWK编程专家,你需要先知道它的内部实现机制,AWK遵循了非常简单的工作流 - 读取,执行和重复,下图描述了AWK的工作流。
这里写图片描述

ReadAWK从输入流(文件,管道或者标准输入)中读取一行,然后存储到内存中。Execute所有的AWK命令都依次在输入上执行。默认情况下,AWK会对每一行执行命令,我们可以通过提供模式限制这种行为。Repeat处理过程不断重复,直到到达文件结尾。程序结构现在,让我们先学习一下AWK的程序结构。BEGIN 语句块BEGIN语句块的语法BEGIN {awk-commands}BEGIN语句块在程序开始的使用执行,它只执行一次,在这里可以初始化变量。BEGIN是AWK的关键字,因此它必须为大写,注意,这个语句块是可选的。BODY 语句块BODY语句块的语法/pattern/ {awk-commands}BODY语句块中的命令会对输入的每一行执行,我们也可以通过提供模式来控制这种行为。注意,BODY语句块没有关键字。END 语句块END语句块的语法END {awk-commands}END语句块在程序的最后执行,END是AWK的关键字,因此必须为大写,它也是可选的。

示例1:

//创建一个文本文件[root@vm20702 wxl]# vim mark.txt 1) 张三 物理 802) 李四 数学 903) 王二 地理 874) 刘大 英语 855) 周五 历史 89//使用下面的命令显示该文件的完整内容[root@vm20702 wxl]# awk '{print}' mark.txt 1) 张三 物理 802) 李四 数学 903) 王二 地理 874) 刘大 英语 855) 周五 历史 89[root@vm20702 wxl]# //使用脚本文件提供AWK命令//awk [options] -f file ....//首先,创建一个包含下面内容的文本文件 command.awk//{print}[root@vm20702 wxl]# vim command.awk{print}[root@vm20702 wxl]# awk -f command.awk mark.txt 1) 张三 物理 802) 李四 数学 903) 王二 地理 874) 刘大 英语 855) 周五 历史 89

AWK标准选项

AWK支持下列命令行标准选项:

1、变量赋值选项

该选项将一个值赋予一个变量,它会在程序开始之前进行赋值,下面的例子描述了该选项的使用
$ awk -v name=Jerry ‘BEGIN{printf “Name = %s\n”, name}’
Name = Jerry

[root@vm20702 wxl]# awk -v name=Jerry 'BEGIN{printf "NAME=%s\n",name}'NAME=Jerry[root@vm20702 wxl]# 

2、–dump-variables[=file] 选项

该选项会输出排好序的全局变量列表和它们最终的值到文件中,默认的文件是 awkvars.out。

[root@vm20702 wxl]# awk --dump-variables ''[root@vm20702 wxl]# lsawkvars.out  command.awk  mark.txt[root@vm20702 wxl]# cat awkvars.out ARGC: number (1)ARGIND: number (0)ARGV: array, 1 elementsBINMODE: number (0)CONVFMT: string ("%.6g")ERRNO: number (0)FIELDWIDTHS: string ("")FILENAME: string ("")FNR: number (0)FS: string (" ")IGNORECASE: number (0)LINT: number (0)NF: number (0)NR: number (0)OFMT: string ("%.6g")OFS: string (" ")ORS: string ("\n")RLENGTH: number (0)RS: string ("\n")RSTART: number (0)RT: string ("")SUBSEP: string ("\034")TEXTDOMAIN: string ("messages")[root@vm20702 wxl]# 

3、–help选项

打印帮助信息。

[root@vm20702 wxl]# awk --help用法: awk [POSIX 或 GNU 风格选项] -f 脚本文件 [--] 文件 ...用法: awk [POSIX 或 GNU 风格选项] [--] '程序' 文件 ...POSIX 选项:           GNU 长选项:    -f 脚本文件     --file=脚本文件    -F fs           --field-separator=fs    -v var=val      --assign=var=val    -m[fr] val    -O          --optimize    -W compat       --compat    -W copyleft     --copyleft    -W copyright        --copyright    -W dump-variables[=file]    --dump-variables[=file]    -W exec=file        --exec=file    -W gen-po       --gen-po    -W help         --help    -W lint[=fatal]     --lint[=fatal]    -W lint-old     --lint-old    -W non-decimal-data --non-decimal-data    -W profile[=file]   --profile[=file]    -W posix        --posix    -W re-interval      --re-interval    -W source=program-text  --source=program-text    -W traditional      --traditional    -W usage        --usage    -W use-lc-numeric   --use-lc-numeric    -W version      --version提交错误报告请参考“gawk.info”中的“Bugs”页,它位于打印版本中的“ReportingProblems and Bugs”一节翻译错误请发信至 translation-team-zh-cn@lists.sourceforge.netgawk 是一个模式扫描及处理语言。缺省情况下它从标准输入读入并写至标准输出。范例:    gawk '{ sum += $1 }; END { print sum }' file    gawk -F: '{ print $1 }' /etc/passwd[root@vm20702 wxl]# 

4、–lint[=fatal] 选项

该选项允许检查程序的不兼容性或者模棱两可的代码,当提供参数 fatal的时候,它会对待Warning消息作为Error。

[root@vm20702 wxl]# awk --lint '' /bin/lsawk: 警告: 命令行中程序体为空awk: 警告: 源文件不以换行符结束awk: 警告: 完全没有程序正文![root@vm20702 wxl]# 

5、–posix 选项

该选项开启严格的POSIX兼容。

6、–profile[=file]选项

该选项会输出一份格式化之后的程序到文件中,默认文件是 awkprof.out。

[root@vm20702 wxl]# awk --profile 'BEGIN{printf"---|Header|--\n"} {print} END{printf"---|Footer|---\n"}' mark.txt > /dev/null [root@vm20702 wxl]# lsawkprof.out  awkvars.out  command.awk  mark.txt[root@vm20702 wxl]# cat awkprof.out     # gawk 配置, 创建 Fri Apr 21 15:30:11 2017    # BEGIN 块    BEGIN {        printf "---|Header|--\n"    }    # 规则    {        print $0    }    # END 块    END {        printf "---|Footer|---\n"    }[root@vm20702 wxl]# 

7、–traditional 选项

该选项会禁止所有的gawk规范的扩展。

8、–version 选项

输出版本号

[root@vm20702 wxl]# awk --versionGNU Awk 3.1.7

基本使用示例

打印某列或者字段

/** mark.text content's1) 张三 物理 802) 李四 数学 903) 王二 地理 874) 刘大 英语 855) 周五 历史 89*/[root@vm20702 wxl]# awk '{print $3 "\t" $4}' mark.txt 物理  80数学  90地理  87英语  85历史  89[root@vm20702 wxl]# 

打印所有的行
默认情况下,AWK会打印出所有匹配模式的行

[root@vm20702 wxl]# awk '/8/ {print $0}' mark.txt1) 张三 物理 803) 王二 地理 874) 刘大 英语 855) 周五 历史 89[root@vm20702 wxl]# //如果BODY部分缺失则默认会执行打印,因此,上述命令和下面这个是等价的 awk '/8/' mark.txt

打印匹配模式的列

[root@vm20702 wxl]# awk '/8/ {print $2 "\t" $4}' mark.txt 张三  80王二  87刘大  85周五  89//任意顺序打印[root@vm20702 wxl]# awk '/8/ {print $4 "\t" $2}' mark.txt 80  张三87  王二85  刘大89  周五[root@vm20702 wxl]# //统计匹配模式的行数[root@vm20702 wxl]# awk '/8/{++cnt} END{print  "Count=", cnt}' mark.txt Count= 4[root@vm20702 wxl]# //打印超过10个字符的行[root@vm20702 wxl]# awk 'length($0) > 10' mark.txt 1) 张三 物理 802) 李四 数学 903) 王二 地理 874) 刘大 英语 855) 周五 历史 89[root@vm20702 wxl]# 

标准AWK变量

ARGC 命令行参数个数,命令行中提供的参数个数
ARGV 存储命令行参数的数组,索引范围从0 - ARGC - 1

[root@vm20702 wxl]# awk 'BEGIN {print "Arguments=",ARGC}' 1 2 3 4Arguments= 5// ARGV 存储命令行参数的数组,索引范围从0 - ARGC - 1。[root@vm20702 wxl]# awk 'BEGIN {for (i=0;i<ARGC-1;i++){printf "ARGV[%d]=%s\n",i,ARGV[i]}}' one two three fourARGV[0]=awkARGV[1]=oneARGV[2]=twoARGV[3]=three[root@vm20702 wxl]#//**** CONVFMT 数字的约定格式代表了数字的约定格式,默认值是**%.6g**$ awk 'BEGIN { print "Conversion Format =", CONVFMT }'Conversion Format = %.6g//**** ENVIRON 环境变量环境变量的关联数组$ awk 'BEGIN { print ENVIRON["USER"] }'root//**** FILENAME 当前文件名$ awk 'END {print FILENAME}' marks.txtmarks.txt//**** FS 输入字段的分隔符代表了输入字段的分隔符,默认值为空格,可以通过-F选项在命令行选项中修改它。$ awk 'BEGIN {print "FS = " FS}' | cat -vteFS =  $$ awk -F , 'BEGIN {print "FS = " FS}' | cat -vteFS = ,$//**** NF 字段数目代表了当前行中的字段数目,例如下面例子打印出了包含大于两个字段的行$ echo -e "One Two\nOne Two Three\nOne Two Three Four" | awk 'NF > 2'One Two ThreeOne Two Three Four//**** NR 行号$ echo -e "One Two\nOne Two Three\nOne Two Three Four" | awk 'NR < 3'One TwoOne Two Three//**** FNR 行号(相对当前文件)与NR相似,不过在处理多文件时更有用,获取的行号相对于当前文件。//**** OFMT 输出格式数字默认值为**%.6g**$ awk 'BEGIN {print "OFMT = " OFMT}'OFMT = %.6g//**** OFS 输出字段分隔符输出字段分隔符,默认为空格$ awk 'BEGIN {print "OFS = " OFS}' | cat -vteOFS =  $//****  ORS 输出行分隔符默认值为换行符$ awk 'BEGIN {print "ORS = " ORS}' | cat -vteORS = $$//**** RSTARTmatch函数匹配的第一次出现位置$ awk 'BEGIN { if (match("One Two Three", "Thre")) { print RSTART } }'9//**** SUBSEP 数组子脚本的分隔符数组子脚本的分隔符,默认为**\034**$ awk 'BEGIN { print "SUBSEP = " SUBSEP }' | cat -vteSUBSEP = ^\$//****  $0 代表了当前行//****  $n 当前行中的第n个字段
0 0
原创粉丝点击