简介
在Linux和Unix操作系统中,文本处理是一个常见的任务。AWK命令是一个强大的文本处理工具,专门进行文本截取和分析,它允许你在文本文件中查找、过滤、处理和格式化数据。本文将深入介绍Linux中的AWK命令,让你了解其基本用法和高级功能,以便更高效地处理文本数据。
什么是AWK?
AWK是一种处理文本文件的编程语言,它得名于其创始人Alfred Aho、Peter Weinberger和Brian Kernighan的姓氏首字母。AWK在命令行中使用,但更多是作为脚本来使用。AWK语言的强大之处在于它可以轻松地执行以下任务:
-
文本搜索和匹配:AWK可以在文本中搜索特定模式或关键字,并执行相应的操作。
-
数据提取和转换:它可以从文本中提取数据,并将其转换成不同的格式。
-
报告生成:AWK可以生成自定义格式的报告,适用于文本文件中的数据分析。
-
文本编辑:它可以用于编辑文本文件,添加、删除或修改文本行。
AWK命令的执行过程
基本语法
awk -v var=value '模式pattern { 动作action }' filename
- awk的指令(patten+action)一定要用单引号 '... ' 括起来,动作一定要用花括号 { ... } 括起;
- 模式可以是正则表达式、条件表达式或两种组合,如果模式是正则表达式要用定界符:/ ;
- 动作之间用 ; 分开;
- 定义自定义变量var,不需要接$符号;
完整语法
awk 'BEGIN{commands}pattern{commands}END{commands}' filename
// 一个awk脚本通常由BEGIN,pattern,END语句块组成。三个部分都是可选的
// 脚本通常是被单引号或双引号包住
awk "BEGIN{commands}pattern{commands}END{commands}" filename
或
awk 'BEGIN {
# 初始化操作(处理数据前,执行的命令。例如,设置变量等)
}
/pattern1/ {
# 当匹配到 pattern1 时执行的操作
}
/pattern2/ {
# 当匹配到 pattern2 时执行的操作
}
END {
# 输出最终结果或进行清理操作(处理数据后,执行的命令)
}' filename
执行过程的详细解释:
- awk 命令启动,并读取 filename 中的文本文件作为输入数据。如果未提供 filename,则默认从标准输入读取数据。
- BEGIN 块中的命令会在处理输入文件之前执行一次。这通常用于初始化变量、设置选项或执行其他预处理操作。
- awk 逐行读取输入文件,并将每一行拆分成字段(默认以空格为字段分隔符,可以使用 -F 选项指定其他分隔符)。
- pattern 块中的命令会在输入行匹配指定的模式时执行。模式可以是正则表达式或其他条件。如果存在多个 pattern 块,则会根据匹配的模式按顺序执行相应的命令。pattern语句块中的通用命令是最重要的部分,是可选的。如果没有提供pattern语句块,则默认执行END{ ... }。
- 在 pattern 块中,你可以访问字段和执行各种操作。例如,可以对字段进行计算、打印匹配行,或根据条件执行不同的操作。
- 当 awk 处理完输入文件的所有行后,它会执行 END 块中的命令。这通常用于输出最终结果、汇总数据或执行清理操作。
- awk 完成处理后,它会将结果打印到标准输出(通常是终端),除非您在脚本中显式使用 print 命令输出结果。
基本用法
在终端中,你可以使用以下的形式运行AWK命令:
1. 最简单的形式:
awk [选项] '{ action }' file.txt
这是最基本的形式,它会将 file.txt 文件的所有行都执行操作action。
选项参数有:
- -F 指定输入文件的字段分隔符,用于将输入行分割为字段。示例:
awk -F, '{ print $1 }' data.txt
在这个示例中,-F, 指定逗号 , 作为字段分隔符,然后打印每行的第一个字段。
- -v 定义一个用户定义变量,可以在脚本中使用。示例:
awk -v name=John '{ print "Hello, " name "!" }' file.txt
在这个示例中,-v 选项定义了一个名为 name 的变量,并将其值设置为 "John",然后在脚本中使用它。
- -f 指定包含 awk 脚本的文件,以便在执行时加载脚本。示例:
awk -f myscript.awk file.txt
在这个示例中,-f 选项指定了一个名为 myscript.awk 的脚本文件,awk 将执行其中的命令。
- -W [option]:启用某些扩展选项。示例:
awk -W version
这将显示 awk 的版本信息。
awk -W help
打印全部awk选项和每个选项的简短说明。
- -E:切换为扩展正则表达式(ERE)模式匹配。示例:
awk -E '/[0-9]+/ { print }' file.txt
在这个示例中,-E 选项允许使用扩展正则表达式模式,匹配包含数字的行。
- -i inplace:在原始文件中进行原地编辑。示例:
awk -i inplace '{ sub("old_pattern", "new_pattern") } 1' file.txt
这将在 file.txt 中查找并替换第一个匹配的 "old_pattern" 为 "new_pattern",并将结果写回原始文件。
- -n:禁用默认的自动打印行为。示例:
awk -n '/pattern/ { print }' file.txt
这将只打印包含 "pattern" 的行,不会自动打印所有行。
- -FPOSIX:使用 POSIX 标准的字段分隔符。示例:
awk -FPOSIX '{ print $1 }' data.txt
这将使用 POSIX 标准的字段分隔符进行字段分割。
- -Wlint:启用 lint 模式,用于检查 awk 脚本中的潜在问题。示例:
awk -Wlint -f myscript.awk file.txt
这将启用 lint 模式并检查 myscript.awk 中的潜在问题。
- -Wsource=program-text:允许在命令行上直接提供 awk 脚本。示例:
awk -Wsource='{ print "Hello, World!" }' file.txt
这将在命令行上直接提供 awk 脚本,然后在 file.txt 上执行。
2. 指定字段分隔符的形式:
awk -F, '{ print $1, $2 }' data.csv
这个形式使用了 -F 选项来指定字段分隔符为逗号,然后打印每行的第一个和第二个字段。
3. 使用脚本文件的形式:
awk -f myscript.awk file.txt
在这个形式中,awk 使用了 -f 选项,后面跟着一个包含 awk 脚本的文件 myscript.awk,并对 file.txt 文件执行该脚本中定义的操作。
4. 设置变量的形式:
awk -v var=value '{ print var, $1 }' file.txt
这个形式使用了 -v 选项来设置一个变量 var,然后将其与文件中的第一个字段一起打印。
5. 条件过滤的形式:
awk 'pattern { action }' filename
- pattern:是一个正则表达式或条件,用于匹配文本中的行。
- action:是在满足条件的行上执行的操作。
- filename:是要处理的文本文件的名称。
这个形式使用了正则表达式模式 /pattern/,只对文件中匹配该模式的行执行操作action。
以下是一个示例,演示了如何使用AWK命令查找并打印包含关键字的行:
awk '/help/ { print }' english.txt
这将在名为english.txt的文件中查找包含关键字"help"的行,并将它们打印到终端。
其它
有时候,AWK命令的形式的部分会有省略,有如下几种情况,举例说明:
1. 只有模式没有动作,结果为显示$0($0 表示整行文本)
awk '/chen/' scores.txt
2. 只有动作没有模式,就直接执行动作
who | awk '{print $2}'
字段和分隔符
内置变量$1
AWK默认使用空格作为字段分隔符。在处理文本时,它将文本行分割成多个字段,你可以使用$1、$2、$3等特殊的内置变量来引用这些字段($0 表示整行文本),它们用于表示当前正在处理的输入行(或记录)的不同字段(列)的值。例如,$1代表文本中第一个字段,$2代表第二个字段,$n 表示第n个字段,以此类推。
以下是一个示例,演示如何使用AWK命令提取文本行中的第二个字段:
awk '{ print $2 }' english.txt
如果文本文件中的字段是以逗号、制表符或其他字符分隔的,你可以使用 -F 选项来指定分隔符。例如,如果文本以逗号分隔,您可以这样使用:
awk -F, '{ print $2 }' english.txt
内置变量FS & OFS
AWK 命令中,用于控制字段的输入和输出分隔符的内置变量:
- 输入分隔符 FS (Field Separator):用于指定字段的输入分隔符。默认情况下,awk 使用空格作为字段分隔符,但你可以使用 -F 选项或在 BEGIN 块中设置 FS 来指定不同的字段分隔符。
- 输出分隔符 OFS (Output Field Separator):用于指定字段的输出分隔符。默认情况下,OFS 为空格,这意味着 awk 在打印输出时会在字段之间插入空格。你可以在 BEGIN 块中设置 OFS 来指定不同的输出字段分隔符。
示例 1
以下是一个示例,演示了如何在 awk 中使用 FS 和 OFS 来控制字段分隔和输出分隔:
假设有一个 CSV 文件 data.csv 包含以下内容:
Alice,90,88,92
Bob,78,85,80
Charlie,92,94,89
可以使