三十分钟学会awk(一)

本文介绍了awk命令行的各种选项,如变量赋值、帮助、lint、POSIX兼容等,并给出了基本使用示例,包括打印文本、列及字段。通过这些,读者可以快速上手awk的基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

Read
AWK从输入流(文件,管道或者标准输入)中读取一行,然后存储到内存中。
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) 张三 物理 80
2) 李四 数学 90
3) 王二 地理 87
4) 刘大 英语 85
5) 周五 历史 89
//使用下面的命令显示该文件的完整内容
[root@vm20702 wxl]# awk '{print}' mark.txt 
1) 张三 物理 80
2) 李四 数学 90
3) 王二 地理 87
4) 刘大 英语 85
5) 周五 历史 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) 张三 物理 80
2) 李四 数学 90
3) 王二 地理 87
4) 刘大 英语 85
5) 周五 历史 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]# ls
awkvars.out  command.awk  mark.txt
[root@vm20702 wxl]# cat awkvars.out 
ARGC: number (1)
ARGIND: number (0)
ARGV: array, 1 elements
BINMODE: 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”页,它位于打印版本中的“Reporting
Problems and Bugs”一节

翻译错误请发信至 translation-team-zh-cn@lists.sourceforge.net

gawk 是一个模式扫描及处理语言。缺省情况下它从标准输入读入并写至标准输出。

范例:
    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/ls
awk: 警告: 命令行中程序体为空
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]# ls
awkprof.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 --version
GNU Awk 3.1.7

基本使用示例

打印某列或者字段

/** mark.text content's
1) 张三 物理 80
2) 李四 数学 90
3) 王二 地理 87
4) 刘大 英语 85
5) 周五 历史 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.txt
1) 张三 物理 80
3) 王二 地理 87
4) 刘大 英语 85
5) 周五 历史 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) 张三 物理 80
2) 李四 数学 90
3) 王二 地理 87
4) 刘大 英语 85
5) 周五 历史 89
[root@vm20702 wxl]# 

标准AWK变量

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

[root@vm20702 wxl]# awk 'BEGIN {print "Arguments=",ARGC}' 1 2 3 4
Arguments= 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 four
ARGV[0]=awk
ARGV[1]=one
ARGV[2]=two
ARGV[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.txt
marks.txt
//**** FS 输入字段的分隔符
代表了输入字段的分隔符,默认值为空格,可以通过-F选项在命令行选项中修改它。
$ awk 'BEGIN {print "FS = " FS}' | cat -vte
FS =  $
$ awk -F , 'BEGIN {print "FS = " FS}' | cat -vte
FS = ,$
//**** NF 字段数目
代表了当前行中的字段数目,例如下面例子打印出了包含大于两个字段的行
$ echo -e "One Two\nOne Two Three\nOne Two Three Four" | awk 'NF > 2'
One Two Three
One Two Three Four
//**** NR 行号
$ echo -e "One Two\nOne Two Three\nOne Two Three Four" | awk 'NR < 3'
One Two
One Two Three
//**** FNR 行号(相对当前文件)
与NR相似,不过在处理多文件时更有用,获取的行号相对于当前文件。
//**** OFMT 输出格式数字
默认值为**%.6g**
$ awk 'BEGIN {print "OFMT = " OFMT}'
OFMT = %.6g
//**** OFS 输出字段分隔符
输出字段分隔符,默认为空格
$ awk 'BEGIN {print "OFS = " OFS}' | cat -vte
OFS =  $
//****  ORS 输出行分隔符
默认值为换行符
$ awk 'BEGIN {print "ORS = " ORS}' | cat -vte
ORS = $
$
//**** RSTART
match函数匹配的第一次出现位置
$ awk 'BEGIN { if (match("One Two Three", "Thre")) { print RSTART } }'
9
//**** SUBSEP 数组子脚本的分隔符
数组子脚本的分隔符,默认为**\034**
$ awk 'BEGIN { print "SUBSEP = " SUBSEP }' | cat -vte
SUBSEP = ^\$
//****  $0 代表了当前行
//****  $n 当前行中的第n个字段
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值