Linux命令-gawk

gawk是什么?

gawk是GNU AWK,是awk的GNU实现版本。awk 是一种强大的文本处理语言,而不仅仅是像 grep 或 sed 那样简单的命令。gawk可以看作是专门为处理结构化文本文件(特别是以空格或制表符分隔的字段)而设计的微型编程语言。
与sed命令相比:
sed 是一个流编辑器,按行处理,主要针对单行进行替换、删除、插入等操作。
gawk 是一个报告生成器,它逐行读取文本,但可以将一行拆分成多个字段,并进行更复杂的逻辑操作,如算术运算、变量赋值、流程控制、函数调用等,最终可以格式化输出结构化报告。

现在基本上主流的linux操作系统中都已经安装了gawk,而且awk命令是一个软连接(符号链接),指向的就是gawk。

kwephis70674332:~ # ll /usr/bin/awk
lrwxrwxrwx 1 root root 4 Aug 11  2025 /usr/bin/awk -> gawk

所以说awk和gawk两个命令,使用哪个都可以,都是一样的,而且很多人还是习惯使用awk。
 

基本语法

gawk [选项] '程序指令' 输入文件1 输入文件2 ...

gawk程序指令的格式是:'/模式/{动作}'

  • 模式:一个条件。gawk 只对满足该条件的行执行 动作。如果模式为空,则对所有行执行动作。
  • 动作:一条或多条语句。语句之间用分号 ; 分隔。如果动作是 print 或 printf 等默认的动作,{} 可以省略。

接下来我们先创建一个示例文件data.txt,就用这个示例文件文件来演示大部分功能用法,内容如下:

  1. 用户ID 用户名 分数 科目
    101 张三 85 数学
    102 李四 92 英语
    103 王五 78 数学
    104 赵六 88 物理
    105 孙七 95 数学

工作原理

gawk 执行过程如下:

  1. 初始化:读取并分析整个程序指令。
  2. 读取:从输入文件(或标准输入)中按行读取记录。
  3. 分割:使用域分隔符(默认是空格或制表符)将每行记录分割成一个个字段。
  4. 执行:

         如果定义了处理模式(BEGIN),则首先执行。

        对每一行输入:

                检查行是否匹配给定的 模式。
                如果匹配,则执行相应的 动作。

        如果定义了处理模式(END),则在处理完所有行后执行。

    5. 输出:在执行过程中,将 print 或 printf 的输出打印到标准输出。

核心概念详解

记录与字段

  • 记录:通常就是指输入的一行文本。
  • 字段:一行文本被分割后的片段。默认的分割符是连续的空格和制表符。

下面是一些专用变量

$0:整行的文本内容。
$1, $2, $3, ...:代表第一个、第二个、第三个...字段。
NF:Number of Fields(当前行的字段数量)。
NR:Number of Records(已处理的记录总数,也就是行号)。
FILENAME:当前正在处理的文件名。
FS:Field Separator(输入字段分隔符),默认为空格。
OFS:Output Field Separator(输出字段分隔符),默认为空格。
RS:Record Separator(记录分隔符),默认为换行符。

    接下来看一个示例

    # 打印 data.txt 文件的每一行,并显示行号和该行字段数
    gawk '{print "行号:", NR, "共", NF, "个字段 ->", $0}' data.txt
    # 输出
    行号: 1 共 4 个字段 -> 用户ID 用户名 分数 科目
    行号: 2 共 4 个字段 -> 101 张三 85 数学
    行号: 3 共 4 个字段 -> 102 李四 92 英语
    ... (后续行省略) ...
    # 只打印用户名(第2个字段)和分数(第3个字段)
    gawk '{print $2,$3}' data.txt
    
    # 输出
    张三 85
    李四 92
    ...

    模式

    模式决定了动作执行的条件。

    • 未定义模式,则对每一行都执行;
    • 正则表达式模式:用 /正则/ 表示,匹配该正则表达式的行会执行动作。
    • 关系表达式模式:如 x > y, x == y, x != y。表达式为真时执行。
    # 打印所有包含 "数学" 的行
    gawk '/数学/{print $0}' data.txt
        
    # 只打印分数大于等于 90 的用户的用户名和分数
    gawk '$3 >= 90 {print $2,$3}' data.txt
    
    # 打印科目是 "数学" 的行
    gawk '$4 == "数学" {print$2, $3}' data.txt
    • BEGIN 模式:在读取任何输入行之前执行一次。通常用于初始化变量、打印表头等。
    • END 模式:在所有输入行处理完毕之后执行一次。通常用于打印汇总信息、统计数据等。

    BEGIN 块在程序开始时运行,打印一个表头。OFS="\t" 将输出字段的分隔符设置为制表符,使对齐更美观。

    # 打印一个漂亮的表格
    gawk '
    BEGIN {
        printf "======= 数学成绩单 =======\n";
        OFS="\t"
    }
    $4=="数学" {
        print$1, $2,$3
    }' data.txt
    
    # 输出
    ======= 数学成绩单 ========
    101    张三	   85
    103	   王五	   78
    105	   孙七	   95

    END模式示例如下:
     

    # 计算 "数学" 科目的平均分
    gawk '
    BEGIN {
        total_score = 0
        count = 0
        print "正在计算数学平均分..."
    }
    $4 == "数学" {
        total_score +=$3
        count++
    }
    END {
        if (count > 0) {
            printf "数学科目平均分是: %.2f\n", total_score / count
        } else {
            print "没有找到数学成绩。"
        }
    }' data.txt
    
    # 输出
    正在计算数学平均分...
    数学科目平均分是: 86.00

    动作

    动作有gawk语句组成,常用的动作介绍如下:

    1、print:输出列表

    • print $1,$3:用默认的 OFS(空格)连接并输出。
    • print 或 print $0:输出整行。
    • print "abc":直接输出字符串。

    2、printf:格式化输出(类似 C 语言),更强大、更精确。

    语法如下:

    printf "格式字符串", 变量1, 变量2, ...

    常用的格式化符有:

    • %d  :整数
    • %f   :浮点数
    • %.2f:保留两位小数的浮点数
    • %s  :字符串
    • \t     :制表符
    • \n    :换行符
    # 格式化输出
    gawk '
    BEGIN {
        printf "%-8s %s\n", "姓名", "分数";
        print "---------- ------"
    } 
    $4=="数学" {
        printf "%-8s %d\n",$2, $3
    }' data.txt
    
    # 输出
    姓名     分数
    ------   ------
    张三     85
    王五     78
    孙七     95

    3、复制和运算

    # 找出最高分
    gawk '
    BEGIN {max_score=0} $3 > max_score {max_score=$3}
    END {print "最高分是:", max_score}
    ' data.txt

    4、流程控制 if-else, for, while

    # 简单的 if-else
    gawk '
    $3 >= 90 {print$2, "成绩优秀"}
    $3 < 90 {print$2, "继续努力"}
    ' data.txt

    常用选项

    -F 或 --field-separator选项:作用是指定字段分隔符。这是最常用的选项之一,例如处理用逗号分隔的 CSV 文件。

    # 在命令行定义一个变量 subject=数学,在程序中使用
    gawk -v subject="数学" -F ',' '$3 == subject {print$1, $2}' data.csv

    -v 或 --assign选项:作用是从命令行向 gawk 程序中传递变量。

    # 在命令行定义一个变量 subject=数学,在程序中使用
    gawk -v subject="数学" -F ',' '$3 == subject {print$1, $2}' data.csv

    假设有一个 sales.txt 文件,记录了各商店的销售额。我们来演示一下gawk在数据分析与统计方面的应用。

    北京店 12000 8000 15000
    上海店 20000 18000 17000
    广州店 9500 11000 10500

    命令编写如下:

    gawk '
    # BEGIN模式
    BEGIN {
        OFS = "\t" # 设置输出字段分隔符为制表符
        print "店名", "总销售额"
        print "--------------------"
    }
    # 动作
    {
        # $1是店名,$2, $3,$4是季度销售额
        store_total = $2 +$3 + $4
        company_total += store_total # 累加到公司总计
        
        printf "%s\t%d\n",$1, store_total
    }
    # END模式
    END {
        print "--------------------"
        print "公司总销售额:", company_total
    }' sales.txt
    
    # 输出
    店名        总销售额
    --------------------
    北京店      35000
    上海店      55000
    广州店      31000

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值