Linux中awk提取列数据需据文件结构选择分隔符:默认空格/制表符自动压缩;非空格分隔符须用-F指定;字段含空格时需正则定位;可加条件筛选并控制输出格式。

Linux 中用 awk 提取列数据,核心是理解字段怎么切、哪一列要什么、输出怎么排。它不是简单敲个 $1 就完事,得看文件真实结构。
默认分隔符下直接取列
awk 默认把连续空格或制表符当分隔符,自动压缩多个空格。适合整齐对齐的文本,比如 ps、ls -l 输出:
- 取第一列:
awk '{print $1}' file.txt - 取第一列和第三列:
awk '{print $1, $3}' file.txt - 取最后一列(不用数有多少列):
awk '{print $NF}' file.txt - 取倒数第二列:
awk '{print $(NF-1)}' file.txt
非空格分隔符必须显式指定
遇到冒号、逗号、竖线等分隔符,不加 -F 就会切错。常见例子:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
-
/etc/passwd取用户名和 UID:awk -F ':' '{print $1, $3}' /etc/passwd - CSV 文件取第 2 和第 4 列:
awk -F ',' '{print $2, $4}' data.csv - Nginx 日志按竖线取状态码和字节数:
awk -F '|' '{print $5, $8}' access.log - 支持多字符分隔符,如冒号或分号:
awk -F '[:;]' '{print $1, $2}' file.txt
字段本身含空格时不能硬切
比如日志里双引号包裹的 User-Agent,内部有空格但属于同一列。这时靠 -F 不行,得用正则定位:
- 用
match()找双引号内容起始位置:awk '{start = match($0, /"([^"]*)"/); if (start) print substr($0, RSTART+1, RLENGTH-2)}' access.log - 用正则定义分隔符,跳过引号内空白:
awk -F '"[^"]*"|\s+' '{print $1, $2}' access.log - 对空格不规整但逻辑上“一个字段一个空格”的文本,强制按多空格切:
awk -F '[[:space:]]+' '{print $1, $NF}' data.txt
带条件筛选再输出列
只对满足条件的行提取列,条件和 print 必须写在同一规则块里,否则容易漏或错:
- 取
/etc/passwd中 UID 大于 1000 的用户名:awk -F ':' '$3 > 1000 {print $1}' /etc/passwd - 从 netstat 输出中提取 ESTABLISHED 连接的本地端口和远程地址:
netstat -tn | awk '$6 == "ESTABLISHED" {print $4, $5}' - 跳过空行和注释行,取
/etc/fstab的设备和挂载点:awk '!/^$/ && !/^\s*#/ {print $1, $2}' /etc/fstab
输出格式也常被忽略:默认用空格连接各列;想用逗号、制表符或固定宽度,得用 OFS 或 printf 控制。不复杂但容易忽略。

















