awk - 字符串与字段过滤

从指定列开始显示后续内容

下面的命令清空前三列,再输出这一行的剩余内容:

awk -F ' ' '{ for (i=1; i<=3; i++) { $i="" }; print $0 }'

输出指定列

awk -F ' ' '{print $0}'       # 显示整行
awk -F ' ' '{print $1}'       # 输出第一列
awk -F ' ' '{print $1,$3}'    # 输出第一、三列
awk -F ' ' '{print $NF}'      # 输出最后一列
awk -F ' ' '{print $(NF-2)}'  # 输出倒数第三列

NF 表示当前记录的字段总数,因此 $NF 是最后一列,$(NF-2) 是倒数第三列。

统计文件行数

time awk 'END {print NR}' FILENAME

过滤重复行

awk '!seen[$0]++' filename

$0 表示当前整行。数组 seen 记录每行出现的次数;第一次出现时表达式为真,awk 执行默认动作并打印整行,之后遇到相同内容时不再输出。这样可以在保留原有顺序的同时去除重复行。

指定多个分隔符

-F 可以接收正则表达式。字符类 [:<>] 表示冒号、小于号或大于号中的任意一个字符。

# 使用冒号、小于号或大于号分隔,输出第二列
awk -F '[:<>]' '{print $2}' filename

示例文件:

foo:bar<123
baz:qux<456

使用冒号或小于号作为分隔符:

awk -F '[:<]' '{print $2}' filename

输出:

bar
qux

对于下面的内容:

foo:bar/baz|qux

命令中的 [:/|] 会匹配冒号、斜杠或竖线,字段是这些匹配之间的文本:

awk -F '[:/|]' '{print $2}' file.txt

输出:

bar

运算符

检查密码字段为空的本地账户:

sudo awk -F: '($2 == "") {print $1}' /etc/shadow

空密码字段可能带来安全风险,应结合系统的认证策略进一步核实。

常用比较运算符:

# 等于
awk '$1 == "pattern" {print $0}'
 
# 不等于
awk '$1 != "pattern" {print $0}'
 
# 大于
awk '$1 > 10 {print $0}'
 
# 小于
awk '$1 < 10 {print $0}'
 
# 大于等于
awk '$1 >= 10 {print $0}'
 
# 小于等于
awk '$1 <= 10 {print $0}'
 
# 匹配正则表达式
awk '$1 ~ /pattern/ {print $0}'
 
# 不匹配正则表达式
awk '$1 !~ /pattern/ {print $0}'

相关命令

参考资料