1. awk 教程

1.1 调用 awk

awk 是一种强大的文本处理工具,在 Linux 系统中广泛应用于日志分析、数据处理等场景。调用 awk 主要有以下三种方式:

1.1.1 命令行方式

基本语法为:

awk (-F filed-separator) 'commands' input-files

其中,-F用于指定分隔符,默认情况下,awk 以空格或制表符作为分隔符。commands是 awk 的命令,input-files则是要处理的文件。例如,我们有一个文件data.txt,内容如下:

apple 3 1.5
banana 5 2.0
cherry 2 1.8

如果我们想以空格为分隔符,打印每一行的第一个和第三个字段,可以使用以下命令:

awk '{print $1,$3}' data.txt

输出结果为:

apple 1.5
banana 2.0
cherry 1.8

如果文件中的字段是以冒号分隔,我们就需要使用-F选项指定分隔符。比如有一个users.txt文件,内容为:

user1:password1:1001
user2:password2:1002
user3:password3:1003

要打印每个用户的用户名(第一个字段)和用户 ID(第三个字段),命令如下:

awk -F: '{print $1,$3}' users.txt

输出:

user1 1001
user2 1002
user3 1003

注意:

 单引号双引号都行,但是要按照规范

场景单引号(')双引号(")
纯正则匹配推荐使用,语法简洁,避免 Shell 干扰也可使用,但需注意转义
包含 Shell 变量无法直接使用,需额外处理直接引用变量,Shell 先解析
正则包含特殊字符自动防止 Shell 解析,直接使用需用反斜杠转义(如\$\+
避免引号嵌套错误适合正则中无单引号的场景适合正则中包含单引号的场景

1.1.2 脚本文件可执行方式

将所有 awk 命令插入一个文件,并使该文件可执行。同时,在脚本文件的首行使用#!/usr/bin/awk -f,这样就可以通过直接键入脚本名称来调用它。
例如,创建一个名为process.awk的文件,内容如下:

#!/bin/awk -f
{print $2}

然后为该文件添加可执行权限:

chmod +x process.awk

假设有一个input.txt文件,内容为:

one two three
four five six
seven eight nine

执行process.awk脚本处理input.txt文件:

./process.awk input.txt

输出结果为:

two
five
eight

如果想要改变分隔符:

#!/bin/awk -f
# 设置字段分隔符为冒号
BEGIN { FS = ":" }   #FS 的英文全称是Field Separator
{ print $1, $3 }

1.1.3 调用外部脚本方式

将所有的 awk 命令插入一个单独文件,然后使用-f选项调用该脚本。语法为:

awk -f awk-script-file input-files

例如,有一个脚本文件calculate.awk,内容如下:

{
sum = $1 + $2
print sum
}

我们有一个数据文件numbers.txt,内容为:

3 5
2 7
4 6

执行命令:

awk -f calculate.awk numbers.txt

输出:

8
9
10

1.2 awk 脚本

1.2.1 模式和动作

任何 awk 语句都由模式和动作组成。模式部分决定动作语句何时触发及触发条件,而动作则是对数据进行的具体操作。如果省略模式部分,动作将对每一行输入数据都执行。
模式可以是条件语句、复合语句或正则表达式,其中有两个特殊字段BEGINENDBEGIN语句用于设置计数、打印表头之类的操作,它会在任何文本浏览动作之前执行。END语句则在 awk 完成对所有输入文本的浏览动作后执行,通常用于打印输出文本总数、结尾状态标志等。
动作通常放在大括号{}内。动作最常见的是打印操作,但也可以包含更长的代码,如if语句、循环语句及循环退出结构等。如果不指明动作,awk 将默认打印出所有输入记录。
例如,我们要处理一个成绩文件grades.txt,内容如下:

Alice 85 90 78
Bob 70 65 80
Charlie 95 88 92

我们想在处理文件前打印表头,处理文件时打印每个学生的姓名和平均成绩,处理完后打印一个结束信息。可以使用以下 awk 脚本:

awk

BEGIN {
print "Student\tAverage Grade"
print "----------------------"
}
{
avg = ($2 + $3 + $4) / 3
print $1 "\t" avg
}
END {
print "----------------------"
print "End of Grades Report"
}

执行该脚本:

awk -f script.awk grades.txtsource files / command-line arguments must contain complete functions or rules
出现这个错误可能是你的大括号未闭合

输出:

Student Average Grade
----------------------
Alice 84.3333
Bob 71.6667
Charlie 91.6667
----------------------
End of Grades Report

1.2.2 域和记录

awk 执行时,会将输入的每一行视为一条记录,并且将记录中的各个部分(以分隔符分隔)标记为$1$2……$n,这种方式称为域标识。当需要指定多个域时,使用逗号,进行分隔,如$1,$3指定的是第一个域和第三个域。如果希望指定整行记录,则可以使用$0
使用print命令执行打印操作,该命令需要用{}括起来。

1.2.2.1 抽取域

以之前的grades.txt文件为例,我们要打印每个学生的姓名(第一个域)和数学成绩(第二个域),命令如下:

awk '{print $1,$2}' grades.txt

输出:

Alice 85
Bob 70
Charlie 95
1.2.2.2 保存 awk 输出

保存 awk 输出结果主要有两种方式:

  • 重定向到文件:这种方式下,屏幕不会显示输出内容,而是将结果保存到指定文件中。例如,将grades.txt文件中每个学生的姓名保存到students.txt文件中,命令为:

awk '{print $1}' grades.txt > students.txt

  • 使用管道将输出结果传给teetee命令可以将输出同时显示在屏幕上并保存到文件中。例如,将grades.txt文件中每个学生的总成绩(三个成绩之和)输出到屏幕并保存到total_grades.txt文件中,命令如下:
awk '{sum=$2+$3+$4; print sum}' grades.txt | tee total_grades.txttee命令不可用的话,下载
yum install coreutils
1.2.2.3 使用标准输入

可以通过多种方法将标准输入作为 awk 的输入源:

  • 直接在命令后跟上文件名,如awk '{print $0}' grades.txt,这里grades.txt的内容会作为标准输入被 awk 读取处理。
  • 使用<符号指定输入文件,如awk '{print $0}' < grades.txt,效果与上一种方法相同。
1.2.2.4 打印所有记录

要打印输入文件的所有记录,使用以下命令:

awk '{print $0}' input_file

其中input_file是要处理的文件名。

1.2.2.5 打印单独记录

只打印特定的域,如之前提到的只打印$1$4

awk '{print $1,$4}' input_file
1.2.2.6 自定义格式打印

我们可以在输出内容中添加注释、自定义分隔符等。例如,对于grades.txt文件,我们要在输出学生姓名和平均成绩时,在上方添加注释 “Student Name” 和 “Average Score”,并使用制表符分隔,命令如下:

awk 'BEGIN {print "Student Name\tAverage Score\n------------------------------"} {avg = ($2 + $3 + $4) / 3; print $1 "\t" avg}' grades.txt

输出:

Student Name Average Score
------------------------------
Alice 84.3333
Bob 71.6667
Charlie 91.6667
1.2.2.7 awk 错误信息提示

在使用 awk 时,如果遇到错误,可以从以下几个方面排查:

  • 确保整个 awk 命令用单引号括起来,因为双引号在 Shell 中可能会导致变量提前展开等问题,影响 awk 命令的执行。
  • 确保命令内所有引号成对出现,无论是单引号还是双引号。
  • 确保用大括号{}括起动作语句,用括号()括起条件语句。
  • 检查是否遗漏了大括号{},尤其是在包含多个动作或复杂条件判断时。
1.2.2.8 awk 键盘输入

如果在执行 awk 命令时没有指定输入文件,awk 会从键盘读取输入。输入完成后,按Ctrl + D组合键结束输入。例如,执行awk '{print $0}',然后在命令行输入一些文本,每输入一行按回车键,输入完成后按Ctrl + D,awk 会打印出你输入的每一行内容。

1.2.3 元字符

awk 支持一些元字符,用于模式匹配等操作,常见的元字符有\^$.()|*+?。其中+?在 grep 或 sed 中可能有不同的行为,但在 awk 中有其特定的含义:

  • +:匹配一个或一个以上前面的单字符。例如,/XY+Z/可以匹配XYZXYYYYZ等。
  • ?:匹配 0 个或一个前面的单字符。例如,/XY?Z/可以匹配XYZXZ
    例如,有一个文件strings.txt,内容为:
XZY
XYZY
XYYYYZY
XZ

要匹配包含XY后面跟着一个或多个Y再跟着Z的字符串,可以使用以下命令:

awk '/XY+Z/' strings.txt

输出:

XYZY
XYYYYZY
[root@free ~]# awk '/XY?Z/' string.txt 
XZY
XYZY
XZ

1.2.4 条件操作符

awk 支持多种条件操作符,用于条件判断:

操作符描述
<小于
<=小于等于
==等于
!=不等于
>大于
>=大于等于
~匹配正则表达式
!~不匹配正则表达式
1.2.4.1 匹配

使用~紧跟正则表达式可以匹配域,也可以使用if语句进行条件判断,条件需要用()括起来。
例如,有一个文件employees.txt,内容如下:

John,Manager,50000
Alice,Engineer,45000
Bob,Engineer,48000

要查询职位是工程师(Engineer)的员工信息(打印出$2匹配Engineer的行),可以使用以下两种方式:

awk '{if ($2~/Engineer/) print $0}' employees.txt为什么不需要分号?
因为 if 语句控制下的 print 是同一个逻辑块的一部分,不是独立的语句。正则表达式的基本语法:
在 awk 中,正则表达式通常用 /pattern/ 表示,其中:
开头的 /:标记正则表达式的开始;
结尾的 /:标记正则表达式的结束;
中间的 pattern:是具体的匹配模式(如 Engineer)。

或者

awk '$2 ~ /Engineer/' employees.txt
1.2.4.2 精确匹配

使用==并用双引号括起条件可以进行精确匹配。例如,要查询薪资为48000的员工信息:

awk '{if ($3 == "48000") print $0}' employees.txt
1.2.4.3 不匹配

使用!~紧跟正则表达式可以实现不匹配域的操作。例如,要查询职位不是经理(Manager)的员工信息:

awk '{if ($2!~/Manager/) print $0}' employees.txt

或者

awk '$2 !~ /Manager/' employees.txt
1.2.4.4 比较

以比较薪资大小为例,要找出薪资大于45000的员工姓名和薪资:

awk '{if ($3 > 45000) print $1,$3}' employees.txt
1.2.4.5 各种匹配
  • 匹配Greengreen

awk '/(G|g)reen/' input_file

  • 匹配$1的第四个字符是a

awk '$1 ~ /^...a/' input_file

  • 匹配YellowBrown

awk '$4 ~ /Yellow|Brown/' input_file

  • 匹配以J开头的行:

awk '$0 ~ /^J/' input_file
1.2.4.6 复合表达式

复合模式或复合操作符用于形成复杂的逻辑操作,复合表达式即为模式间通过使用复合操作符互相结合起来的表达式。常用的复合操作符有&&(逻辑与)和||(逻辑或):

  • &&(AND):符号两边的条件必须同时为真。例如,要查询职位是工程师且薪资大于45000的员工信息:

awk '{if ($2 == "Engineer" && $3 > 45000) print $0}' employees.txt

  • ||(OR):符号两边的条件只要有一个为真即可。例如,要查询职位是经理或者薪资大于48000的员工信息:

awk '{if ($2 == "Manager" || $3 > 48000) print $0}' employees.txt

1.2.5 awk 内置变量

awk 有许多内置变量,用于设置环境信息、获取输入输出相关的状态等。以下是一些常用的内置变量:

  • ARGC:表示命令行参数的个数。例如,执行awk -v var1=value1 -v var2=value2 -f script.awk file1 file2ARGC的值为5(包括awk命令本身、两个-v选项及两个文件名)。
  • ARGV:是一个数组,存储命令行参数的排列。ARGV[0]通常是awk命令本身,ARGV[1]及后续元素为命令行参数。
  • FNR:与NR类似,用于记录输入的行数。不同之处在于,FNR在处理多个文件时,对每个文件都会从1开始计数,而NR是对所有输入文件的总行数进行计数。例如,有两个文件file1.txtfile2.txt,在处理file1.txt时,FNRNR1开始递增,当处理完file1.txt开始处理file2.txt时,NR继续递增,而FNR又从1开始。
  • FS:用于指定输入字段的分隔符。可以在BEGIN块中定义,也可以使用-F选项在命令行指定。例如,BEGIN {FS=":"}将输入字段分隔符设置为冒号。
  • RS:输入的记录分隔符,默认是换行符,即文本按一行一行输入。可以修改这个变量来改变记录的分隔方式。例如,BEGIN {RS="\n\n"}可以将连续两个换行符作为记录分隔符,适用于处理段落等以空行分隔的文本。
  • OFS:输出字段分隔符,默认是空格。可以修改为其他字符,如制表符\t或逗号等。例如,BEGIN {OFS="|"}会将输出的字段用竖线分隔。
  • ORS:输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕。可以修改为其他字符,如BEGIN {ORS=","}会将输出的记录用逗号分隔,最后一个记录后也会有逗号。
    例如,我们要统计一个文件中每行的字段数,并输出行号、每行内容及字段数,使用以下脚本:

{
print NR, $0, NF
}

这里NR表示行号,NF表示当前行的字段数。假设文件example.txt内容为:

apple banana cherry
dog cat mouse

执行awk '{print NR, $0, NF}' example.txt,输出:

1 apple banana cherry 3
2 dog cat mouse 3

再如,我们想以冒号为输入分隔符,以逗号为输出分隔符,打印文件data.csv的第一和第三个字段:

BEGIN {
FS=":"
OFS=","
}
{
print $1,$3
}

假设data.csv内容为:

1:apple:red
2:banana:yellow
3:grape:purple

执行该脚本,输出:

1,red
2,yellow
3,purple

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89840.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89840.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/89840.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器需要备案吗?在哪些地区需要备案?

&#x1f3af; 服务器是否需要备案&#xff1f; 是否需要备案&#xff0c;关键看以下两个因素&#xff1a; 服务器所在地&#xff08;机房位置&#xff09; 网站面向的访问群体&#xff08;境内或境外&#xff09; &#x1f3f7; 中国大陆&#xff08;境内&#xff09;服务器…

HarmonyOS学习3---ArkUI

1、组件 1.1、基础组件 1.2、布局容器 1.3、页面导航 1.4、其他组件 2、ArkTs/C混合开发&#xff0c;高性能编码 3、布局能力&交互归一 4、实时开发预览

Java学习第十五部分——MyBatis

目录 一.概述 二.特点 三.组件 四.Mapper 五.配置文件 六.使用步骤 七.高级功能 八.优点缺点 九.项目实战 1.打开idea创建一个Java项目&#xff0c;构建系统选“Maven”​ 2.创建完成后若依赖报错&#xff0c;可通过下载或重新加载来解决​ 3.配置pom.xml文件&…

小企业如何搭建本地私有云服务器,并设置内部网络地址提供互联网访问

在数字化时代&#xff0c;很多普通公司小企业规模的&#xff0c;利用本地小型服务器或计算机搭建私有云服务器&#xff0c;不仅可以提升数据管理效率&#xff0c;还能保障业务数据的安全性和灵活性。以下是为小企业量身定制的私有云服务器搭建指南&#xff0c;及最后附无公网IP…

MySQL 八股文【持续更新ing】

MySQL 八股文【持续更新ing】 文章目录 MySQL 八股文【持续更新ing】前言一、MySQL的存储引擎有哪些&#xff1f;他们之间有什么区别&#xff1f;二、MySQL InnoDB 引擎中的聚簇索引和非聚簇索引有什么区别&#xff1f;1.InnoDB 中的聚簇索引2.InnoDB 中的非聚簇索引 三、MySQL…

每日算法刷题Day42 7.5:leetcode前缀和3道题,用时2h

7. 3026.最大好子数组和(中等,学习) 3026. 最大好子数组和 - 力扣&#xff08;LeetCode&#xff09; 思想 1.给你一个长度为 n 的数组 nums 和一个 正 整数 k 。 如果 nums 的一个子数组中&#xff0c;第一个元素和最后一个元素 差的绝对值恰好 为 k &#xff0c;我们称这个…

Linux操作系统之文件(四):文件系统(上)

前言&#xff1a; 我们前几篇文章讲了缓冲区与重定向的有关概念&#xff0c;这些设计是linux系统的核心机制&#xff0c;对系统性能、资源管理和用户操作灵活性有重要意义。 不涉及一些硬件就不可能让大家清楚地去理解文件系统&#xff0c;所以这篇文章&#xff0c;我将会从计…

java中,stream的filter和list的removeIf筛选速度比较

在 Java 里&#xff0c;Stream 的filter和 List 的removeIf筛选效率要依据具体情形来判断。 1. 操作本质有别 Stream 的 filter&#xff1a; 它是一种中间操作&#xff0c;不会立刻执行&#xff0c;而是把筛选条件记录下来。只有遇到终端操作时&#xff0c;才会开始处理元素。…

Python(28)Python循环语句指南:从语法糖到CPython字节码的底层探秘

目录 引言一、推导式家族全解析1.1 基础语法对比1.2 性能对比测试 二、CPython实现揭秘2.1 字节码层面的秘密2.2 临时变量机制 三、高级特性实现3.1 嵌套推导式优化3.2 条件表达式处理 四、性能优化指南4.1 内存使用对比4.2 执行时间优化技巧 五、最佳实践建议六、总结&#x1…

深度分析:Microsoft .NET Framework System.Random 的 C++ 复刻实现

深度分析&#xff1a;Microsoft .NET Framework Random 的 C 复刻实现 核心原理与算法结构 本实现基于 Knuth 减随机数生成器&#xff08;Subtractive Random Number Generator&#xff09;&#xff0c;是 .NET Framework 中 System.Random 的精确复刻。其核心特点包括&#x…

[论文阅读] 人工智能 | 在非CUDA硬件上运行几何学习:基于Intel Gaudi-v2 HPU的PyTorch框架移植实践

在非CUDA硬件上运行几何学习&#xff1a;基于Intel Gaudi-v2 HPU的PyTorch框架移植实践 论文标题&#xff1a;PyTorch-based Geometric Learning with Non-CUDA Processing Units: Experiences from Intel Gaudi-v2 HPUs arXiv:2507.01031 (cross-list from cs.LG) PyTorch-ba…

Python-多线程-threading

1 需求 2 接口 3 示例 4 参考资料 Python treading 模块 | 菜鸟教程

2025年- H91-Lc199-- 62.不同路径(多维动态规划)--Java版

1.题目描述 2.思路 dp含义&#xff1a;代表到当前位置的路径数 递推公式&#xff1a;dp[i][j]dp[i-1][j]dp[i][j-1] dp数组初始化&#xff0c;我们要确保第一行和第一列是有值的. dp数组的遍历顺序&#xff1a;我们需要从左往右遍历&#xff0c;从上往下遍历。并且把第一行和第…

char 不是 Java 中的 2 字节(16 位)吗? 为什么用 UTF-8 编码写入时,一个中文要占 3 个字节?

char 不是 Java 中的 2 字节&#xff08;16 位&#xff09;吗&#xff1f; 为什么用 UTF-8 编码写入时&#xff0c;一个中文要占 3 个字节&#xff1f; ✅ 一、Java 中的 char 是什么&#xff1f; Java 的 char 是一个 固定大小的 2 字节&#xff08;16 位&#xff09;类型&am…

【Elasticsearch】检索排序 分页

检索排序 & 分页 1.测试数据准备2.排序功能2.1 简单字段排序2.2 多字段排序2.3 日期排序 3.分页功能3.1 基础分页3.2 深度分页&#xff08;不推荐大数据量使用&#xff09;3.3 使用 search_after 进行高效分页 4.综合示例&#xff1a;高亮排序分页5.实践建议 1.测试数据准备…

Delta、Jackknife、Bootstrap

用班级平均身高的案例&#xff0c;展示 ​Delta、Jackknife、Bootstrap​ 的完整计算过程。 ​0. 数据准备​ ​原始数据&#xff08;4个学生的身高&#xff09;​​&#xff1a; 真实均值&#xff08;目标统计量&#xff09;​​&#xff1a; ​1. Delta 方法&#xff08;公式…

企业智脑技术架构设计:紧贴企业场景规划面向未来的发展趋势与实现路径

摘要 本文深入探讨了企业智脑技术架构的设计理念与发展趋势&#xff0c;分析了当前企业智能化转型的技术需求与挑战&#xff0c;提出了一个面向未来的企业智脑技术架构设计方案。文章从底层技术支撑、核心能力构建、应用场景适配、安全合规保障以及未来发展路径五个维度展开论…

新手向:Python方向讲解

从NASA火星任务到TikTok推荐算法&#xff0c;从自动化脚本到量子计算&#xff0c;Python用import antigravity重新定义了编程边界 一、设计哲学&#xff1a;优雅明确的编程禅学 Python之禅&#xff08;import this&#xff09;&#xff1a; 优美胜于丑陋&#xff08;Beautifu…

Chrome谷歌浏览器插件ModHeader,修改请求头,开发神器

文章目录一、介绍与下载二、使用一、介绍与下载 ModHeader顾名思义就是让我们可以自定义HTTP请求头或者是重写响应头&#xff0c;包括新增请求头/响应头或者覆盖Chrome浏览器设置的请求头的默认值&#xff0c;同时还可以根据URL Pattern来只对特定网站生效。 有条件的同学可以…

SEW:无监督预训练在语音识别中的性能-效率权衡

摘要 本文研究了自动语音识别&#xff08;ASR&#xff09;中预训练模型的性能-效率权衡问题。我们聚焦于 wav2vec 2.0&#xff0c;并形式化了多种影响模型性能和效率的架构设计。基于所有观察结果&#xff0c;我们提出了 SEW&#xff08;Squeezed and Efficient Wav2vec&#…