十九、awk 命令提取文件中的关键字段
1、awk
是一种强大的文本处理语言,专为按字段(列)分析数据而设计。是类似 sed 的行处理软件,awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。
gawk是 GNU 版本的awk,功能最全,Linux 默认使用它。- 核心思想:将输入视为行(record)和字段(field),自动分割并处理。
gawk 擅长:
- 按字段(列)处理结构化文本(如 CSV、日志、/etc/passwd)
- 条件过滤
- 数值计算
- 生成格式化报表
- 它不是用来“编辑文件”的,而是用来“分析和转换数据流”的。
awk文件的每行数据都被称为记录,默认以空格或制表符为分隔符,每条记录被分成若干字段(列),awk每次从文件中读取一条记录。
sed命令常用于一整行的处理,而awk比较倾向于将一行分成多个“字段”然后再进行处理,也从不修改源文件。
工作原理:
逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。
语法:
gawk [选项] '模式 {动作}' 文件
- 模式(Pattern):决定对哪些行执行动作(可选)
- 动作(Action):用
{}包裹的操作(如打印、计算) - 若省略模式,则对所有行执行动作
- 若省略动作,默认是
{print}
| 选项 | 说明 |
|---|---|
-F |
指定字段分隔符(默认空格或制表符),以每条记录中存在的字符作为分隔符 |
-v var=value |
定义变量 |
-f script.awk |
从文件读取 awk 脚本 |
awk常见的内建变量(可直接用):
记录(Record) = 一行(默认以换行符\n分隔)
字段(Field) = 一行中的列(默认以空格/制表符分隔)
| 变量 | 全称 | 默认值 | 作用 |
|---|---|---|---|
$0 |
整行记录 | — | 当前处理的整行内容 |
$1, $2, ..., $NF |
字段 | — | 第1、2、...、最后一个字段,当前处理行的第n个字段(第n列)。 |
FS |
Field Separator | 空格或制表符 | 列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用相同 |
OFS |
Output Field Separator | 空格 | 输出字段分隔符(print 时字段间的分隔符) |
NF |
Number of Fields | 动态计算 | 当前行的字段总数 |
NR |
Number of Records | 动态递增 |
当前处理的行的行号(序数)。 |
FNR |
File Number of Records | 动态递增 | 当前文件的行号(多文件时重置) |
FILENAME |
— | 当前文件名 | 正在处理的文件名 |
RS |
Record Separator | \n |
行分隔符,awk根据RS定义的行分隔符,把数据切割成多条记录。预设值是’\n’ |
ORS |
Output Record Separator | \n |
输出记录分隔符(print 后加的内容) |
2、模式的 6 种主要写法(由简到繁)
1)正则表达式模式(最常用)
用 /.../ 包裹,匹配整行是否包含该模式。
/error/ // 行中包含 "error" /^root/ // 行以 "root" 开头 /[0-9]{3}/ // 行包含连续3个数字(GNU awk 支持) $1 ~ /admin/ // 第1列匹配 "admin" $NF !~ /\.log$/ // 最后一列不以 .log 结尾
~ 表示“匹配正则”,!~ 表示“不匹配”
2)关系表达式模式
任何返回 true/false 的表达式都可作模式。
$3 > 1000 // 第3列数值 > 1000 NF == 5 // 字段数等于5 NR % 2 == 0 // 偶数行 $1 == "alice" // 第1列等于 "alice" length($0) > 80 // 行长度超过80字符
表达式为真(非0/非空)时,执行动作。
3)范围模式(行区间)
格式:起始模式, 结束模式
NR==5, NR==10 // 第5行到第10行 /^START/, /^END/ // 从包含 "START" 的行到包含 "END" 的行 $1=="user", $1=="end" // 从 user 行到下一个 end 行
范围模式是“触发式”的,一旦开始,直到结束条件满足才停止。
4)布尔组合模式
用 &&(与)、||(或)、!(非)组合多个条件。
$3 > 100 && $4 < 50 // 第3列>100 且 第4列<50 /ERROR/ || /FATAL/ // 包含 ERROR 或 FATAL !/^#/ // 不以 # 开头(非注释行)
5)BEGIN 和 END 块
它们不匹配任何输入行,只控制执行时机。
BEGIN:处理第一行前执行(初始化)END:处理完最后一行后执行(汇总)
语法:
BEGIN { // 初始化代码:设置变量、FS/OFS、打印表头等,BEGIN 中 没有 $0, $1, NR, FILENAME 等行相关变量(因为还没读文件) } // 主处理块(可选模式 + 动作) /pattern/ { // 处理每一行 } END { // 汇总代码:输出统计结果、总计、平均值等 }
执行顺序:
- 执行 BEGIN 块(只执行一次)
- 逐行读取文件,对每行执行主处理块
- 所有行处理完后,执行 END 块(只执行一次)
如:
1: awk ' 2: BEGIN { // 打印表头和分隔线 3: printf "%-15s %8s %s\n", "Username", "UID", "Shell" 4: print "----------------------------------------" 5: } 6: -F: { 7: printf "%-15s %8d %s\n", $1, $3, $7 8: } 9: END { // 打印底部横线,NR:已处理的总行数(即 /etc/passwd 的总行数) 10: print "----------------------------------------" 11: print "Total users:", NR 12: } 13: ' /etc/passwd
6)空模式(省略模式)
没有匹配模式
{ print $1 } // 等价于:对所有行执行
如:awk对字段(列)的提取
字段提取:提取文本中的一列数据并打印出来
字段相关内置变量:
$0 表示整行文本
$1 表示文本行中的第一个数据字段
$2 表示文本行中的第二个数据字段
$N 表示文本行中的第N个数据字段
$NF 表示文本行中的最后一个数据字段
// 打印第1列(用户名) gawk '{print $1}' /etc/passwd // 打印最后1列(shell) gawk '{print $NF}' /etc/passwd // 打印第1列和第3列 gawk '{print $1, $3}' /etc/passwd ///etc/passwd 用 : 分隔 gawk -F: '{print $1, $6}' /etc/passwd // 指定分隔符(-F) // 输出:用户名 + 家目录 // CSV 文件(逗号分隔) gawk -F',' '{print $2}' data.csv // 只处理包含 "root" 的行 gawk '/root/ {print $0}' /etc/passwd // 条件过滤(模式匹配) // 第3列 > 1000 的用户(UID) gawk -F: '$3 > 1000 {print $1}' /etc/passwd // 行号在 5~10 之间 gawk 'NR>=5 && NR<=10 {print NR ": " $0}' file.txt // 求第2列总和 gawk '{sum += $2} END {print "Total:", sum}' sales.txt // END 块:所有行处理完后执行(用于汇总) // 求平均值 gawk '{total += $1; count++} END {print "Avg:", total/count}' numbers.txt // 最大值 gawk 'max=="" || $1>max {max=$1} END {print "Max:", max}' data.txt
// 格式化输出(printf) gawk -F: ' BEGIN { printf "%-15s %8s %s\n", "User", "UID", "Home" } { printf "%-15s %8d %s\n", $1, $3, $6 } ' /etc/passwd // 输出 User UID Home root 0 /root john 1001 /home/john
greatwall@greatwall-pc:~/test$ awk -F' ' '{print $2}' employee.txt // 以空格作为分隔符 Doe,CEO Smith,IT Reddy,Sysadmin Ram,Developer Miller,Sales greatwall@greatwall-pc:~/test$ awk -F'0' '{print $2}' employee.txt // 以数字0作为分隔符 1,John Doe,CEO 2,Jason Smith,IT Manager 3,Raj Reddy,Sysadmin 4,Anand Ram,Developer 5,Jane Miller,Sales Manager
本文来自博客园,作者:chao_xiong,转载请注明原文链接:https://www.cnblogs.com/chao-xiong/p/16198369.html

浙公网安备 33010602011771号