awk详细教程-基础篇

24 篇文章 0 订阅
本文详细介绍了awk工具的环境准备、语法形式、选项参数,重点讲解了变量设置、运算符和内置函数,包括算数函数、字符串函数、日期函数以及如何利用awk进行文件操作和系统调用。适合深入理解文本处理和Unix环境下的高级分析。
摘要由CSDN通过智能技术生成

1.前言

awk是Unix环境下一个强大的文本分析工具,相对于grep和sed,awk在其对数据分析并生成报告时,显得尤为强大。它还有许多精心设计的特性,支持awk脚本语言执行,从而极大程度提高重用率。其功能就是把文件默认逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。这里之所以说默认,是因为这里也是有配置项进行修改的。

2.环境准备

这里主要准备一个文本文件,名称建议为awk.txt,内容如下:

1 this is a test
2 Are you like awk
3 This's a awk
4 There are orange,apple,mongo
I like awk

2.语法形式

awk [选项参数] 'script' var=value [file(s)/管道流]
awk [选项参数] -f scriptfile var=value [file(s)/管道流]

2.1 选项参数

在awk工具中,选项参数有很多,这里常用的参数如下:

2.1.1 -f scripfile or --file scriptfile

从脚本文件中读取awk命令。建议:针对于简单的awk命令,直接在命令行书写即可,如果是较为复杂而且常用的功能,建议编写awk脚本语言,便于后期重复利用。

准备awk脚本文件awk.awk,内容如下:

{print "hello"}

执行如下命令:

awk -f awk.awk awk.txt

执行结果如下:

在上图中,我们先查看脚本文件awk.awk和文本文件awk.txt两个文件的内容,下面是输出结果。大家可以想一下为什么这里输出5个hello?

2.1.2 -F fs or --field-separator fs

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

这里需要注意以下两点:

1)分隔符是支持正则表达式的;

2)这个参数和内置变量FS是等效的(关于内置变量我们后面会说到)。

针对上面的文本的例子,我们按照字母i和逗号作为分隔符,进行分解,代码如下:

#当前记录的第n个字段,字段间由FS分隔
awk -F "[i,]" '{print $1"=="$2"=="$3"=="$4}' awk.txt

针对于上面输出的结果,大家感兴趣可以自行分析一下。

2.1.3 -v var=value or --asign var=value

赋值一个用户定义变量,如果是需要多个变量,则需要使用多个-v.

下面的例子是我们输出两列行号,一列从3开始,一列从13开始:

#$0表示输出一整行
awk -v a=3 -v b=13 '{print a++,b++,$0}' awk.txt

2.2 处理文本

在AWK工具中,处理的文本来源主要包括文本和管道输入流,其中文本包括支持多个文本。

1)文件处理

awk '{print $0}' 1.txt 2.txt

2)管道输入

ll|awk '{print $0}'

3.运算符

运算符描述
= += -= *= /= %= ^= **=赋值
?:C条件表达式
||逻辑或
&&逻辑与
~ 和 !~匹配正则表达式和不匹配正则表达式
< <= > >= != ==关系运算符
空格连接
+ -加,减
* / %乘,除与求余
+ - !一元加,减和逻辑非
^ ***求幂
++ --增加或减少,作为前缀或后缀
$字段引用
in数组成员

这里我们简单举几个例子,感兴趣的可以各自尝试一下:

# 1)提取第一列为1的行
awk '$1==1{print $0}' awk.txt
# 2)提取第一列为1或者3的行
awk '$1==1 || $1==3{print $0}' awk.txt
# 3)提取第一列不为数字的行
awk '$1 !~ /[0-9]/{print $0}' awk.txt

4. 内置变量

变量描述
$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的描述中提到"文件默认逐行的读入,以空格为默认分隔符将每行切片",既然是默认,一定有修改的地方;针对于“以空格为默认分隔符将每行切片”,前面已经提到过可以通过参数-F进行设置,当然也可以通过内置变量FS设置,对于“文件默认逐行的读入”,可以通过RS设置有意思的是输出的分隔符符合分行的设置可以通过OFS和ORS设置。下面我们就这四个命令做以举例,其他的大家可以自行尝试。

变量的设置可以通过两种方式:1)通过参数-v进行设置,一种是通过awk命令进行设置。我们通过一个例子将这两种都演示一遍。在这里,输入的变量我们通过-v设置,输出的变量我们通过命令设置。

1)创建一个文本:

name=zhangsan,age=18,address=hebei

2)针对上述文本,我们以","为记录分隔符(即行分隔符,默认为回车),以“=”为字段分隔符(默认为空格),解析脚本。最终输出,我们以"&&"为行分隔符,以“:”为列分隔符,具体脚本如下:

#关于BEGIN的用法,后面会说道,这里只要知道这个指令是在解析文本之前只执行一次即可
awk -v FS="=" -v RS="," 'BEGIN{OFS=":";ORS="&&"}{print $1,$2}' awk2.txt

3)输出结果

其他情况大家可以自行增删改相关参数即可。

5.内置函数

5.1 算数函数

文本处理工具,对于数字的处理还是用处不大的,所以用处倒不是很大,感兴趣的可以了解一下

函数名说明
srand( [Expr] )将 rand 函数的种子值设置为 Expr 参数的值,或如果省略 Expr 参数则使用某天的时间。返回先前的种子值。
sqrt( x )返回 x 平方根。
sin( x )返回 x 的正弦;x 是弧度。
rand( )返回任意数字 n,其中 0 <= n < 1。
log( x )返回 x 的自然对数。
int( x )返回 x 的截断至整数的值。
exp( x )返回 x 幂函数。
cos( x )返回 x 的余弦;x 是弧度。
atan2( y, x )返回 y/x 的反正切。

5.2 字符串函数

这里的函数就非常有使用价值了,毕竟这是文本处理工具嘛。

函数说明
gsub( Ere, Repl, [ In ] )gsub 是全局替换( global substitution )的缩写。除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行。
sub(regex,sub,string)sub 函数执行一次子串替换。它将第一次出现的子串用 regex 替换。第三个参数是可选的,默认为 $0。
substr(str, start, l)substr 函数返回 str 字符串中从第 start 个字符开始长度为 l 的子串。如果没有指定 l 的值,返回 str 从第 start 个字符开始的后缀子串。
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 参数指定的表达式并返回最后生成的字符串。
strtonum(str)strtonum 将字符串 str 转换为数值。 如果字符串以 0 开始,则将其当作十进制数;如果字符串以 0x 或 0X 开始,则将其当作十六进制数;否则,将其当作浮点数。

1)gsub、sub 使用

#gsub使用
awk 'BEGIN{info="今天是2021年4月4日";gsub(/[0-9]+/,"**",info);print info}'
#输出:今天是**年**月**日
#----------------------
#sub使用
awk 'BEGIN{info="今天是2021年4月4日";sub(/[0-9]+/,"**",info);print info}'
#输出:今天是**年4月4日

2)截取字符串(substr使用)

awk 'BEGIN{info="今天date是2021年4月4日";print substr(info,4,10);}'
#输出:ate是2021年4

3)格式化字符串输出(sprintf使用)

格式符说明
%d十进制有符号整数
%u十进制无符号整数
%f浮点数
%s字符串
%c单个字符
%p指针的值
%e指数形式的浮点数
%x%X 无符号以十六进制表示的整数
%o无符号以八进制表示的整数
%g自动选择合适的表示法
awk 'BEGIN{info=sprintf("%s今年%d岁","小明",26);print(info)}'

5.3 日期函数

函数名说明
mktime( YYYY MM DD HH MM SS[ DST])生成时间格式
strftime([format [, timestamp]])格式化时间输出,将时间戳转为时间字符串
systime()得到时间戳,返回从1970年1月1日开始到当前时间(不计闰年)的整秒数

5.4 其他函数

system执行特定的命令然后返回其退出状态。返回值为 0 表示命令执行成功;非 0 表示命令执行失败。

我觉得这个函数是最重要的函数,这个也是我学习这个工具的一个强大动力,他的威力在于可以可以调用linux系统命令。

5.4.1 实例1

现在我要创建文件名为1-20的文件夹:

1)创建一个文本文件createfile.txt,1-20编号;

2)注意这里使用逗号隔开的,所以我们的命令如下:

awk -v RS="," '{system("mkdir "$1)}' createfile.txt

5.4.2 实例2 

删除章节5.4.1创建的文件夹。这里我们通过ll命令的方式删除。

1)首先我们执行ll命令:

2)输入命令

ll |awk 'NR!=1 && $9 ~ /^[0-9]{1,2}$/{system("rm -rf "$9)}'

注意:

        $9 ~ //这里是包含的意思,所以在正则表达式中必须加上“^”以...开始的符号和“$”以...结尾的符号。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

surpassLiang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值