Linux文件处理三剑客之awk

2023年 11月 15日 103.7k 0

背景

awk语言,出自三位创始人姓氏的首字母(Alfred Aho 、Peter Weinberger 和 Brian Kernighan)。在2011年针对发起者Alfred Aho的采访中,问起为何会创作了awk语言,Alfred的回答是在上世纪80年代初,为了追踪经费预算或者追踪学生的成绩,同时避免用C或者其它语言长篇的语句来实现,所以创造了awk语言,旨在用少量的代码行数就能实现如此的功能。同样,与后期Larry Wall创作了Perl语言一样,这些大师们出于某个实际应用,又不想写一堆代码,所以正是在这种程序员独有的“懒惰”与“完美主义”的双重人格下,极简而又优雅的语言,就被创造了出来。

awk是一种优良的文本处理工具,它不仅是 Linux 中也是任何环境中现有的最强大的数据处理引擎之一,提供了极其强大的功能:样式装入、流控制、数学运算符、进程控制语句等等。而且内置了许多变量和函数,可以便于使用者在用awk处理文本的时候,简洁而又方便得通过少量代码就能获取所需信息。

格式

    在awk中,格式会严重影响输出的正确性,通常而言,两种常见的格式如下:

awk '{pattern + action}'  input_file
awk 'pattern {action}' input_file

    比如说,如果文件中第一列匹配关键字abc,那就打印最后一列:

  •     第一种格式,awk '{if($1 ~ /abc/) print $NF}' input_file

  •     第二种格式,awk '$1 ~ /abc/ {print $NF}' input_file

参数

    通常情况下, awk命令常用参数有-F与-v

    -F 输入内容的分隔符(field)

    -v 某个可以传入的参数(var=val)

    比如输入内容分隔符是竖线(|),如果要打印每一行的列数,可以运行

awk -F '|' '{print NF}' input_file

    如果要通过-v打印出“列数是”的关键字,可以运行

awk -F '|' -v 'dp=列数是' '{print dp, NF}' input_file

特殊变量

    细心的读者在上述用例中,已经发现了NF这样的关键字,其实在awk中,除了NF,还有很多其它类似的特殊变量:

  • $0:代表整行

  • $1:代表分隔后第一列;同理$2代表第二列,以此类推

  • NF:number of fields,代表一行中列的个数,所以$NF表示最后一列

  • NR:number of rows,代表该行的行号

  • FS:field separator,代表输入文件的列分隔符

  • OFS:output field separator,代表输出内容的列分隔符

    所以,如果要打印某个文件的第2行,通过awk可以如下执行:

awk 'NR == 2 {print}' input_file #通过格式二书写

    如果要将input_file(分隔符是'|')的第一列替换成test:

awk -F '|' '{$1="test";print}' input_file

    细心的读者同样也会发现,输出内容的分隔符与原始文件不一致,所以如果要将上述输出内容依旧保持文件最开始的分隔符'|':

awk -F '|' '{$1="test";OFS=FS;print}' input_file

内置函数

    为了文字处理更加便捷,awk开发了一系列的内置函数,通过这些函数能极大简化代码的行数,本文选取常用函数进行介绍:

  • length,长度

  • gsub,替换

  • substr,截取

  • split,分隔

length

    例如,用'|'作为分隔符,将input_file文件每一行的长度以及第二列的长度打印出来:

awk -F '|' '{print length,length($2)}' input_file

    注:上述length如果代表的是一行长度,会包括分隔符'|'

gsub

    对gsub函数而言,有两种格式,分别是:

  • gsub("a","b"),将单行中所有的"a"替换为"b"

  • gsub("a","b",sth),将sth中所有的"a"替换为"b"

    比如,如果要将input_file中,所有的"i"字符,替换为"%",可以运行:

awk -F '|' '{gsub("s","%");OFS=FS;print}' input_file

    如果要将第二列的所有的"s"替换为"%",可以运行:

awk -F '|' '{gsub("s","%",$2);OFS=FS;print}' input_file


substr

    与gsub类似,substr也有两种格式

  • substr(sth,num),将sth从num开始截图到最后

  • substr(sth,num1,num2),将sth从num1开始往后截取num2位

    注:上述sth可以是某个字符串,也可以是某个变量或者$1/$2这样某一个列

    例如将以'|'作为分隔符的第一列,从第2位开始截取到最后:

awk -F '|' '{a=substr($1,2);print a}' input_file

    或者从第2位开始往后截取2位:

awk -F '|' '{a=substr($1,2,2);print a}' input_file

split

    split主要作用是将某一串字符串,根据某个关键字来分隔,并将分割完的结果保存到某个数组中,格式如下:

  • split(sth,数组名,"分隔符")

    表示将sth按照“分隔符”切分,并将切分后的结果保存到数组“数组名”中。

    比如将字符串"this|is|a|test"按照"|"切分,并打印第二部分内容

echo "this|is|a|test" | awk '{split($0,arr,"|");print arr[1]}'

    注:上述arr为人为定义的一个数组名称,并且数组的下标从1开始

运算与判断

    在任何一门编程语言中,离不开各式各样的运算以及判断,awk支持多种运算,这些运算与C语言提供的基本相同:如+、-、*、/、%等等,同时awk也支持C语言中类似++、--、+=、-=、=+、=-之类的功能,这给熟悉C语言的使用者编写awk程序带来了极大的方便。作为对运算功能的一种扩展,awk还提供了一系列内置的运算函数(如log、sqr、cos、sin等等)和一些用于对字符串进行操作(运算)的函数(如length、substr等等)。这些函数的引用大大的提高了awk的运算功能。

    在判断上,awk也提供了相当多功能,如常用的==(等于)、!=(不等于)、>(大于)、>=(大于等于)、

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论