前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >awk 简明教程

awk 简明教程

作者头像
用户3147702
发布2022-06-27 12:31:12
1.2K0
发布2022-06-27 12:31:12
举报
文章被收录于专栏:小脑斧科技博客

1. 概述

awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。 数据可以来自标准输入、一个或多个文件,或其它命令的输出。 它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。 它在命令行中使用,但更多是作为脚本来使用。 awk 的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。 awk 分别代表其作者姓氏的第一个字母因为它的作者是三个人,分别是 Alfred Aho、Brian Kernighan、Peter Weinberger。 gawk是awk的GNU版本,它提供了 Bell 实验室和 GNU 的一些扩展。

2. awk 命令格式和选项

2.1. 调用命令

代码语言:javascript
复制
awk [options] 'script' var=value file(s)

或者。

代码语言:javascript
复制
awk [options] -f scriptfile var=value file(s)

可以运行 awk 命令或脚本。

2.2. 命令选项

awk 命令选项

选项

意义

-F fs <b>or</b> —field-separator fs

指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:

-v var=value <b>or</b> —asign var=value

赋值一个用户定义变量

—f scripfile <b>or</b> —file scriptfile

从脚本文件中读取awk命令

-mf nnn

限制分配给nnn的最大块数目,只能用于 gawk

-mr nnn

限制记录的最大数目,只能用于 gawk

3. 模式和操作

awk 脚本是由若干个可选的模式和操作组成的:

代码语言:javascript
复制
awk pattern { action } ...

如: awk ’/root/‘ test,或 awk ’$3 < 100’ test。

模式和操作都是可选的,如果没有模式,则action应用到全部记录,如果没有action,则输出匹配全部记录默认情况下,每一个输入行都是一条记录,但用户可通过RS变量指定不同的分隔符进行分隔。

3.1. 模式

awk 命令的可选模式

模式

意义

/正则表达式/

使用正则表达式过滤

关系表达式

可以用下面即将介绍的运算符表中的任意多个运算符组成

模式匹配表达式

用运算符~(匹配)和~!(不匹配)

模式,模式

指定一个行的范围该语法不能包括BEGIN和END模式

BEGIN

让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量

END

让用户在最后一条输入记录被读取之后发生的动作

3.2. 操作

操作由一人或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。 主要有四部份: 1. 变量或数组赋值 2. 输出命令 3. 内置函数 4. 控制流命令

如:

代码语言:javascript
复制
awk '$1 + $2 < 100' test

如果第一和第二个域相加大于100,则打印这些行。

代码语言:javascript
复制
awk '$1 > 5 && $2 < 10' test

如果第一个域大于5,并且第二个域小于10,则打印这些行。

4. 环境变量

awk 中的环境变量

环境变量

意义

$n

当前记录的第n个字段,字段间由FS分隔

$0

完整的输入记录

ARGC

命令行参数的数目

ARGIND

命令行中当前文件的位置(从0开始算)

ARGV

包含命令行参数的数组

CONVFMT

数字转换格式(默认值为%.6g)

ENVIRON

环境变量关联数组

ERRNO

最后一个系统错误的描述

FIELDWIDTHS

字段宽度列表(用空格键分隔)

FILENAME

当前文件名

FNR

同NR,但相对于当前文件

FS

字段分隔符(默认是任何空格)

IGNORECASE

如果为真,则进行忽略大小写的匹配

NF

当前记录中的字段数

NR

当前记录数

OFMT

数字的输出格式(默认值是%.6g)

OFS

输出字段分隔符(默认值是一个空格)

ORS

输出记录分隔符(默认值是一个换行符)

RLENGTH

由match函数所匹配的字符串的长度

RS

记录分隔符(默认是一个换行符)

RSTART

由match函数所匹配的字符串的第一个位置

SUBSEP

数组下标分隔符(默认值是\034)

5. 运算符

awk 运算符

运算符

意义

= += -= = /= %= ^= *=

赋值

? :

条件表达式

&&

逻辑或,逻辑与

~ ~!

匹配正则表达式和不匹配正则表达式

< <= > >= != ==

关系运算符

+ - * / &

加减乘除,取余

++ —

自增,自减

^

求幂

$

字段引用

in

数组成员判断

6. 变量

6.1. 外部传入变量

awk 可以在调用的时候使用 -v 参数指定外部赋值的变量:

代码语言:javascript
复制
awk '$1 {count = count + $2 + $3; print count}' test -v count=10

6.2. 内部变量

变量可以直接创建和赋值。 域变量也可被赋值和修改,如。

代码语言:javascript
复制
awk '{$2 = 100 + $1; print }' test

7. BEGIN 和 END 模块

BEGIN模块后紧跟着动作块,这个动作块在awk处理任何输入文件之前执行,END不匹配任何的输入文件,但是执行动作块中的所有动作,它在整个输入文件处理完成后被执行。

8. 条件语句

代码语言:javascript
复制
{ if (expression) {
        statement; statement; ...
    }
    else if (expression) {
        statement; statement; ...
    }
    else if (expression) {
        statement; statement; ...
    }
    else {
        statement; statement; ...
    }
}

9. 循环

awk 中有三种循环:while,for 和 special for。

9.1. while 循环

代码语言:javascript
复制
awk '{ i = 1; while ( i <= NF ) { print NF,$i; i++}}' test

9.2. for 循环

代码语言:javascript
复制
awk '{for (i = 1; i<NF; i++) print NF,$i}' test

9.3. special for 循环

代码语言:javascript
复制
'{ for (item in arrayname) { print item,arrayname[item] } }'

9.4. next 语句

直接读取下一行,然后从头开始执行awk脚本。 类似于 C 语言中的 continue,但是 next 语句并非用于循环中。

代码语言:javascript
复制
{ if ($1 ~/test/) { next } else { print } }

10. 数组

10.1. 求数组长度

使用 length(arr) 可以求出数组长度。

代码语言:javascript
复制
awk 'BEGIN { info="it is a test"; lens=split(info,tA," "); print length(tA),lens; }'

10.2. 数组排序

使用 asort 可以对数组排序,返回数组长度。

代码语言:javascript
复制
awk 'BEGIN { info="it is a test"; split(info,tA," "); print asort(tA); }'

10.3. 输出数组内容

无序输出

有序输出

10.4. 判断键是否存在

if (key in array)

代码语言:javascript
复制
awk 'BEGIN { tB["a"]="a1"; tB["b"]="b1"; if( "c" in tB) { print "ok"; }; for(k in tB) { print k, tB[k]; } }'

10.5. 删除键值

delete array[key]

代码语言:javascript
复制
awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";delete tB["a"];for(k in tB){print k,tB[k];}}'

11. 多维数组的使用

内建变量 SUBSEP 用来保存多维数组各维度间的分隔符,默认为“,”。

代码语言:javascript
复制
awk 'BEGIN {
    for(i=1;i<=9;i++)
    {
        for(j=1;j<=9;j++) 
        {
            tarr[i,j]=i*j;
        }
    }
    for(m in tarr)             
    {

        split(m,tarr2,SUBSEP);
        print tarr2[1],"*",tarr2[2],"=",tarr[m];
    }
}'
代码语言:javascript
复制
awk 'BEGIN{
    for(i=1;i<=9;i++)
    {
        for(j=1;j<=9;j++) 
        {
            tarr[i,j]=i*j;
            print i,"*",j,"=",tarr[i,j];
        }
    }
}'

12. 内建函数

12.1. 算术函数

awk 的内建算数函数

函数

意义

atan2( y, x )

返回 y/x 的反正切

cos( x )

返回 x 的余弦;x 是弧度

sin( x )

返回 x 的正弦;x 是弧度

exp( x )

返回 x 幂函数

log( x )

返回 x 的自然对数

sqrt( x )

返回 x 平方根

int( x )

返回 x 的截断至整数的值

rand( )

返回任意数字 n,其中 0 <= n < 1

srand( [Expr] )

将 rand 函数的种子值设置为 Expr 参数的值,或如果省略 Expr 参数则使用某天的时间返回先前的种子值

12.2. 字符串函数

awk 的内建字符串函数

函数

意义

gsub( Ere, Repl, [ In ] )

除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行,。

sub( Ere, Repl, [ In ] )

用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。

index( String1, String2 )

在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。

length [(String)]

返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。

blength [(String)]

返回 String 参数指定的字符串的长度(以字节为单位)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。

substr( String, M, [ N ] )

返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。如果未指定 N 参数,则子串的长度将是 M 参数指定的位置到 String 参数的末尾 的长度。

match( String, Ere )

在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。

split( String, A, [Ere] )

将 String 参数指定的参数分割为数组元素 A[1], A[2], . . ., A[n],并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数组中的元素用字符串值来创建。

tolower( String )

返回 String 参数指定的字符串,字符串中每个大写字符将更改为小写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。

toupper( String )

返回 String 参数指定的字符串,字符串中每个小写字符将更改为大写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。

sprintf(Format, Expr, Expr, . . . )

根据 Format 参数指定的 printf 子例程格式字符串来格式化 Expr 参数指定的表达式并返回最后生成的字符串。

表中所有的 Ere 都可以是正则表达式。

12.3. 格式化输出 printf

awk printf 的参数格式

格式符

说明

%d

十进制有符号整数

%u

十进制无符号整数

%f

浮点数

%s

字符串

%c

单个字符

%p

指针的值

%e

指数形式的浮点数

%x

%X 无符号以十六进制表示的整数

%o

无符号以八进制表示的整数

%g

自动选择合适的表示法

12.4. 时间函数

awk 的时间函数

函数

意义

mktime( YYYY MM DD HH MM SS[ DST])

生成时间格式

strftime([format [, timestamp]])

格式化时间输出,将时间戳转为时间字符串 具体格式,见下表.

systime()

得到时间戳,返回从1970年1月1日开始到当前时间(不计闰年)的整秒数

awk 日期格式符

格式符

意义

%a

星期几的缩写(Sun)

%A

星期几的完整写法(Sunday)

%b

月名的缩写(Oct)

%B

月名的完整写法(October)

%c

本地日期和时间

%d

十进制日期

%D

日期 08/20/99

%e

日期,如果只有一位会补上一个空格

%H

用十进制表示24小时格式的小时

%I

用十进制表示12小时格式的小时

%j

从1月1日起一年中的第几天

%m

十进制表示的月份

%M

十进制表示的分钟

%p

12小时表示法(AM/PM)

%S

十进制表示的秒

%U

十进制表示的一年中的第几个星期(星期天作为一个星期的开始)

%w

十进制表示的星期几(星期天是0)

%W

十进制表示的一年中的第几个星期(星期一作为一个星期的开始)

%x

重新设置本地日期(08/20/99)

%X

重新设置本地时间(12:00:00)

%y

两位数字表示的年(99)

%Y

当前月份

%Z

时区(PDT)

%%

百分号(%)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小脑斧科技博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 概述
  • 2. awk 命令格式和选项
    • 2.1. 调用命令
      • 2.2. 命令选项
      • 3. 模式和操作
        • 3.1. 模式
          • 3.2. 操作
          • 4. 环境变量
          • 5. 运算符
          • 6. 变量
            • 6.1. 外部传入变量
              • 6.2. 内部变量
              • 7. BEGIN 和 END 模块
              • 8. 条件语句
              • 9. 循环
                • 9.1. while 循环
                  • 9.2. for 循环
                    • 9.3. special for 循环
                      • 9.4. next 语句
                      • 10. 数组
                        • 10.1. 求数组长度
                          • 10.2. 数组排序
                            • 10.3. 输出数组内容
                              • 10.4. 判断键是否存在
                                • 10.5. 删除键值
                                • 11. 多维数组的使用
                                • 12. 内建函数
                                  • 12.1. 算术函数
                                    • 12.2. 字符串函数
                                      • 12.3. 格式化输出 printf
                                        • 12.4. 时间函数
                                        领券
                                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档