awk
简介
awk
是 Linux/UNIX 系统中的一种强大文本处理工具,逐行读取输入文本,默认以空格或 Tab 键作为分隔符,并按模式或条件执行编辑命令。其功能强大,灵活性高,可用于数据格式化输出、数据筛选等操作,广泛应用于 Shell 脚本和自动化任务中。
基本功能
- 默认情况下,
awk
以空格或 Tab 键作为字段分隔符,并将多个连续的空格压缩为一个分隔符。 awk
按照指定的匹配模式逐行读取输入文本,对符合条件的内容进行格式化输出或过滤处理。- 默认情况下,
awk
的操作是逐行查找指定的行,并打印找到的行。
使用场景
awk
可以在无交互的情况下实现相当复杂的文本操作,例如:
- 查找特定模式匹配的行。
- 格式化输出匹配的内容。
- 结合 Shell 脚本进行自动化任务处理。
原理
基本语法
awk
命令的基本格式如下:
awk '<pattern> <action>' <input-file>
<pattern>
:指定要匹配的模式。<action>
:指定对匹配的行要执行的操作。<input-file>
:输入文件,可以是一个或多个文件。
例如:awk '{print $1, $2}' file.txt
将打印文件 file.txt
中每行的第一个和第二个字段。
工作过程
awk
的工作过程分为以下三个步骤:
-
执行
BEGIN
语句块:- 在
awk
开始读取输入流之前,执行BEGIN{...}
语句块中的语句。通常用于变量初始化、打印表头等。这是一个可选的语句块。
awk 'BEGIN {print "Header: Column1 Column2"} {print $1, $2}' file.txt
- 在
-
读取和处理输入行:
awk
从文件或标准输入(stdin)逐行读取内容,然后执行pattern {action}
语句块。awk
会对每一行重复此过程,直到文件被读取完毕。pattern
是可选的,如果未指定,则默认执行{print}
,即打印每一行。
-
执行
END
语句块:- 当所有行读取完毕时,执行
END{...}
语句块。通常用于输出汇总信息或处理结果。这也是一个可选的语句块。
awk 'END {print "Processing Complete!"}' file.txt
- 当所有行读取完毕时,执行
工作原理
sed
通常用于整行处理,而awk
更适合将一行分成多个“字段”并逐个字段进行处理。- 默认情况下,
awk
使用空格或 Tab 键作为字段的分隔符。处理结果可以通过print
函数将字段数据打印出来。
格式、选项和内置变量
格式
awk 选项 '模式或条件 {操作}' 文件1 文件2...
常用选项
-F "分隔符"
:指明输入时用到的字段分隔符,默认的分隔符是若干个连续的空白符。-v var=value
:变量赋值,可以定义自定义变量。
模式或条件 和 操作的符号
' '
: 模式或条件和操作需要用单引号' '
括起来,例如'模式或条件 {操作}'
。{}
:大括号外指定条件(或模式),大括号内指定操作。,
:用逗号指定连续的行范围。例如,NR == 1, NR == 5
将匹配从第 1 行到第 5 行的所有行。||
:逻辑“或”操作,用于指定不连续的行条件。例如,$1 == "error" || $2 == "warning"
,表示匹配第一列为"error"
或第二列为"warning"
的行。&&
:逻辑“与”操作,表示“且”,用于指定多个条件同时满足。例如,$1 > 100 && $2 < 200
,表示第一列大于100
且第二列小于200
的行。
示例
awk '{print $1, $2, $3}' file.txt
,将打印每行的第 1、2、3 个字段。没有明确的模式或条件,所以 awk
会处理文件 file.txt
的每一行,逐行执行 {print $1, $2, $3}
的操作部分。
常用内置变量
$0
:当前处理的行的整行内容,打印所有字段。$n
:当前处理行的第n
个字段(第n
列)。NR
:当前处理的行的行号(序数)。NF
:当前处理的行的字段个数,$NF
代表最后一个字段。FS
:输入字段分隔符(列分隔符)。默认为空格或制表位。可用-F
设置,作用相同,单引号可省,如-F ':'
或-F:
。使用FS
时必须用=""
,如FS=":"
。OFS
:输出字段分隔符(列分隔符)。FILENAME
:当前被处理的文件名。RS
:输入行分隔符。默认值是"\n"
。awk从文件中读取时,将根据RS的定义把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。
示例
基本打印用法
在 awk
中,默认逐行读取输入文本并根据指定的操作进行处理和输出。
-
不写任何操作:
awk ''
什么都不写,不会有任何输出效果。
-
默认打印每行:
awk '{print}'
当
{print}
不指定任何参数时,默认打印每一行的内容。 -
控制打印输出:
-
使用
0
和1
作为条件控制打印行为:awk '0{print}' test1.txt
由于条件为
0
(假),不打印任何内容。awk '1{print}' test1.txt
由于条件为
1
(真),打印文件test1.txt
的所有内容。
-
-
打印整行内容:
awk '{print $0}' test1.txt
$0
代表整行内容,awk
会逐行读取test1.txt
并打印每一行的全部内容。 -
打印指定列:
$1
只取每行的第一列,可以对行进行切片,输出特定列。
-
打印行号:
awk '{print NR}' test1.txt
NR
是内置变量,表示当前的行号。此命令将打印每行的行号。 -
打印行号及其对应内容:
awk '{print NR, $0}' test1.txt
打印每行的行号和整行内容,比
sed
更直观地展示内容。 -
打印指定行:
-
打印第 3 行的内容:
awk 'NR==3{print}' test1.txt
-
打印第 3 到第 5 行的内容(逗号):
awk 'NR==3,NR==5{print}' test1.txt
-
打印第 3 行和第 5 行的内容(分号):
awk 'NR==3;NR==5{print}' test1.txt
-
使用正则表达式打印第 3 到第 5 行的内容:
awk '(NR>=3)&&(NR<=5){print}' test1.txt
-
奇偶行打印
-
打印偶数行:
awk 'NR%2==0{print}' test1.txt
NR%2==0
表示行号能够被2
整除(偶数行)。 -
打印奇数行:
awk 'NR%2==1{print}' test1.txt
NR%2==1
表示行号不能被2
整除(奇数行)。
awk运算
awk
支持基本的算术运算,并可以在 BEGIN
块中执行:
-
基本加法:
awk 'BEGIN{print 100+200}'
输出
300
。 -
浮点数加法:
awk 'BEGIN{print 10.2+20.3}'
输出
30.5
。 -
乘法:
awk 'BEGIN{print 10.2*20.3}'
输出
207.06
。 -
除法:
awk 'BEGIN{print 10.2/20.3}'
输出
0.502463
。 -
减法:
awk 'BEGIN{print 10.2-20.3}'
输出
-10.1
。 -
幂运算:
-
使用
*
或^
进行幂运算:
输出9
和8
。awk 'BEGIN{print 3**2}' # 或者 awk 'BEGIN{print 2^3}'
-