【shell】awk命令用法详解

一、基本概念

awk 是 Linux/Unix 中功能强大的文本处理编程工具,其核心特点包括:

  • 按行处理文本数据,支持字段(列)级操作
  • 内置变量、运算符、控制流(条件/循环)及函数。
  • 适用于数据提取、统计、格式化输出等场景。
  • 名称来自其三位创始人姓氏首字母(Aho, Weinberger, Kernighan)。

二、语法结构
awk [选项] '模式 {动作}' 文件1 文件2...     # 直接编写脚本
awk [选项] -f 脚本文件 文件1 文件2...      # 从文件读取脚本

基本执行流程

  1. 逐行读取输入文件。
  2. 根据模式匹配当前行,若匹配则执行动作
  3. 默认输出处理后的行(除非动作中明确禁止)。

三、常用选项
选项说明
-F fs指定输入字段分隔符(默认空格/TAB)
-v var=value定义变量(可在脚本中使用)
-f script.awk从文件读取awk脚本
-O启用优化处理(仅GNU awk支持)
--csv以CSV模式解析输入(Gawk 4.0+)

四、核心语法要素
1. ​内置变量
变量说明
$0当前行的全部内容
$1$2...第1、2个字段(列)
NF当前行的字段总数(列数)
NR当前处理的行号(累计所有文件)
FNR当前文件的行号(各文件独立计数)
FS输入字段分隔符(默认为空格/TAB)
OFS输出字段分隔符(默认为空格)
FILENAME当前处理的文件名
2. ​模式(Pattern)​
  • 空模式:匹配所有行(如 {print $0})。
  • 正则匹配/正则表达式/
    示例awk '/error/ {print NR,$0}' log.txt(输出含"error"的行及其行号)。
  • 范围模式模式1, 模式2(匹配从模式1到模式2之间的行)。
  • 条件表达式:如 NR > 10$3 == "admin"
3. ​动作(Action)​
  • 用 {} 包裹,包含一个或多个语句。
  • 常用操作:printprintf, 算术运算, 流程控制(if/elseforwhile)等。
4. ​BEGIN与END块
  • BEGIN:在处理输入前执行一次
    示例awk 'BEGIN {FS=":"; OFS="\t"} {print $1,$3}' /etc/passwd
  • END:在处理完所有输入后执行一次
    示例awk '{sum+=$1} END {print "总和=", sum}' data.txt

五、典型应用示例
1. ​基础字段处理
# 提取日志中的IP和访问次数(假设第1列为IP)
awk '{ip_count[$1]++} END {for(ip in ip_count) print ip, ip_count[ip]}' access.log

# 格式化输出:列对齐(printf)
awk '{printf "%-15s %10d\n", $1, $3}' sales.csv
  • 打印文件的所有内容

    awk '{ print }' file.txt

    这实际上等同于 cat file.txt,因为 awk 默认会对每一行执行 print 操作。

  • 打印文件的第二列

    假设文件 file.txt 的字段由空格分隔:

    awk '{ print $2 }' file.txt
  • 使用逗号作为字段分隔符打印第二列

    awk -F, '{ print $2 }' file.txt
  • 打印行号和行内容

    awk '{ print NR, $0 }' file.txt
  • 计算每行的字段总和

    假设文件 file.txt 中的字段是数字,且由空格分隔:

    awk '{ sum = 0; for (i = 1; i <= NF; i++) sum += $i; print sum }' file.txt
  • 打印文件中的特定行

    打印文件中的第三行:

    awk 'NR == 3 { print }' file.txt
  • 基于模式匹配打印行

    打印包含 "error" 的行:

    awk '/error/ { print }' file.txt
  • 设置输出字段分隔符

    使用逗号作为输出字段分隔符打印第二和第三列:

    awk -F' ' 'BEGIN { OFS = "," } { print $2, $3 }' file.txt
  • 使用变量

    在命令行中设置变量 x 并打印第 x 列:

    x=3 awk -v col=$x '{ print $col }' file.txt
  • 从文件中读取 awk 程序

    将 awk 程序保存在 script.awk 文件中,并处理 file.txt

    awk -f script.awk file.txt

    script.awk 内容示例:

    { print $2, $3 }
2. ​条件筛选与计算
# 筛选第3列大于100的行,并计算平均值
awk '$3 > 100 {sum+=$3; count++} END {if(count>0) print "平均值=", sum/count}' data.txt

# 输出奇数行(结合NR)
awk 'NR % 2 == 1' file.txt
3. ​文本重组
# 将逗号分隔文件转为JSON
awk -F, 'BEGIN {print "["} NR>1 {printf "  {\"name\":\"%s\",\"age\":%d},\n", $1, $2} END {print "]"}' users.csv

# 合并多个文件的特定列
awk '{print FILENAME, $2}' file1.txt file2.txt
4. ​高级处理
# 统计单词频率(忽略大小写)
awk '{for(i=1;i<=NF;i++) words[tolower($i)]++} END {for(w in words) print w, words[w]}' text.txt

# 处理多行记录(如空行分隔的块)
awk -v RS="" '{print "块", NR, "有", NF, "个字段"}' blocks.txt

 


六、内置函数
函数说明
字符串处理
length(str)返回字符串长度
substr(s, start, len)提取子字符串
split(s, arr, sep)分割字符串到数组
数学运算
int(x)取整数部分
rand()生成0-1的随机数
时间处理
systime()获取当前时间戳
strftime(format, timestamp)格式化时间

七、注意事项
  1. 字段分隔符

    • 使用 -F 或 BEGIN {FS="..."} 指定分隔符(支持正则)。
    • 处理CSV时注意引号包裹的字段(建议用 --csv 或专用工具)。
  2. 性能优化

    • 避免在大文件中频繁使用print $0,明确指定输出字段。
    • 使用数组时注意内存占用,及时删除无用元素(delete array[key])。
  3. 兼容性

    • 不同系统下的awk实现(如mawk、gawk)可能功能有差异,建议明确指定#!/usr/bin/gawk -f
  4. 正则表达式

    • 使用 ~ 和 !~ 进行匹配(如 $2 ~ /^[0-9]+$/)。

通过灵活运用模式匹配、字段操作和脚本逻辑,awk可高效完成复杂文本处理任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浩瀚之水_csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值