深入了解 Linux 中的 AWK 命令:文本处理的瑞士军刀

简介

在Linux和Unix操作系统中,文本处理是一个常见的任务。AWK命令是一个强大的文本处理工具,专门进行文本截取和分析,它允许你在文本文件中查找、过滤、处理和格式化数据。本文将深入介绍Linux中的AWK命令,让你了解其基本用法和高级功能,以便更高效地处理文本数据。


什么是AWK?

AWK是一种处理文本文件的编程语言,它得名于其创始人Alfred Aho、Peter Weinberger和Brian Kernighan的姓氏首字母。AWK在命令行中使用,但更多是作为脚本来使用。AWK语言的强大之处在于它可以轻松地执行以下任务:

  1. 文本搜索和匹配:AWK可以在文本中搜索特定模式或关键字,并执行相应的操作。

  2. 数据提取和转换:它可以从文本中提取数据,并将其转换成不同的格式。

  3. 报告生成:AWK可以生成自定义格式的报告,适用于文本文件中的数据分析。

  4. 文本编辑:它可以用于编辑文本文件,添加、删除或修改文本行。


AWK命令的执行过程

基本语法

awk  -v  var=value  '模式pattern { 动作action }'  filename
  •  awk的指令(patten+action)一定要用单引号 '... ' 括起来,动作一定要用花括号 { ... } 括起;
  • 模式可以是正则表达式、条件表达式或两种组合,如果模式是正则表达式要用定界符:/ ;
  • 动作之间用 ; 分开;
  • 定义自定义变量var,不需要接$符号;

完整语法

awk 'BEGIN{commands}pattern{commands}END{commands}' filename

或 

awk 'BEGIN {# 初始化操作(处理数据前,执行的命令。例如,设置变量等)
}/pattern1/ {# 当匹配到 pattern1 时执行的操作
}/pattern2/ {# 当匹配到 pattern2 时执行的操作
}END {# 输出最终结果或进行清理操作(处理数据后,执行的命令)
}' filename

执行过程的详细解释:

  1. awk 命令启动,并读取 filename 中的文本文件作为输入数据。如果未提供 filename,则默认从标准输入读取数据。
  2. BEGIN 块中的命令会在处理输入文件之前执行一次。这通常用于初始化变量、设置选项或执行其他预处理操作。
  3. awk 逐行读取输入文件,并将每一行拆分成字段(默认以空格为字段分隔符,可以使用 -F 选项指定其他分隔符)。
  4. pattern 块中的命令会在输入行匹配指定的模式时执行。模式可以是正则表达式或其他条件。如果存在多个 pattern 块,则会根据匹配的模式按顺序执行相应的命令。
  5. 在 pattern 块中,您可以访问字段和执行各种操作。例如,可以对字段进行计算、打印匹配行,或根据条件执行不同的操作。
  6. 当 awk 处理完输入文件的所有行后,它会执行 END 块中的命令。这通常用于输出最终结果、汇总数据或执行清理操作。
  7. awk 完成处理后,它会将结果打印到标准输出(通常是终端),除非您在脚本中显式使用 print 命令输出结果。

基本用法

在终端中,你可以使用以下的形式运行AWK命令:

1. 最简单的形式

awk [选项] '{ action }' file.txt

这是最基本的形式,它会将 file.txt 文件的所有行都执行操作action。

选项参数有:

  • -F 指定输入文件的字段分隔符,用于将输入行分割为字段。示例:
awk -F, '{ print $1 }' data.txt
在这个示例中,-F, 指定逗号 , 作为字段分隔符,然后打印每行的第一个字段。
  • -v 定义一个用户定义变量,可以在脚本中使用。示例:
awk -v name=John '{ print "Hello, " name "!" }' file.txt
在这个示例中,-v 选项定义了一个名为 name 的变量,并将其值设置为 "John",然后在脚本中使用它。
  • -f 指定包含 awk 脚本的文件,以便在执行时加载脚本。示例:
awk -f myscript.awk file.txt
在这个示例中,-f 选项指定了一个名为 myscript.awk 的脚本文件,awk 将执行其中的命令。
  • -W [option]:启用某些扩展选项。示例:
awk -W version
这将显示 awk 的版本信息。
awk -W help
打印全部awk选项和每个选项的简短说明。
  • -E:切换为扩展正则表达式(ERE)模式匹配。示例:
awk -E '/[0-9]+/ { print }' file.txt
在这个示例中,-E 选项允许使用扩展正则表达式模式,匹配包含数字的行。
  • -i inplace:在原始文件中进行原地编辑。示例:
awk -i inplace '{ sub("old_pattern", "new_pattern") } 1' file.txt
这将在 file.txt 中查找并替换第一个匹配的 "old_pattern" 为 "new_pattern",并将结果写回原始文件。
  • -n:禁用默认的自动打印行为。示例:
awk -n '/pattern/ { print }' file.txt
这将只打印包含 "pattern" 的行,不会自动打印所有行。
  • -FPOSIX:使用 POSIX 标准的字段分隔符。示例:
awk -FPOSIX '{ print $1 }' data.txt
这将使用 POSIX 标准的字段分隔符进行字段分割。
  • -Wlint:启用 lint 模式,用于检查 awk 脚本中的潜在问题。示例:
awk -Wlint -f myscript.awk file.txt
这将启用 lint 模式并检查 myscript.awk 中的潜在问题。
  • -Wsource=program-text:允许在命令行上直接提供 awk 脚本。示例:
awk -Wsource='{ print "Hello, World!" }' file.txt
这将在命令行上直接提供 awk 脚本,然后在 file.txt 上执行。

2. 指定字段分隔符的形式

awk -F, '{ print $1, $2 }' data.csv

这个形式使用了 -F 选项来指定字段分隔符为逗号,然后打印每行的第一个和第二个字段。

3. 使用脚本文件的形式

awk -f myscript.awk file.txt

在这个形式中,awk 使用了 -f 选项,后面跟着一个包含 awk 脚本的文件 myscript.awk,并对 file.txt 文件执行该脚本中定义的操作。

4. 设置变量的形式

awk -v var=value '{ print var, $1 }' file.txt

这个形式使用了 -v 选项来设置一个变量 var,然后将其与文件中的第一个字段一起打印。

5. 条件过滤的形式

awk 'pattern { action }' filename
  • pattern:是一个正则表达式或条件,用于匹配文本中的行。
  • action:是在满足条件的行上执行的操作。
  • filename:是要处理的文本文件的名称。

这个形式使用了正则表达式模式 /pattern/,只对文件中匹配该模式的行执行操作action。

以下是一个示例,演示了如何使用AWK命令查找并打印包含关键字的行:

awk '/help/ { print }' english.txt

这将在名为english.txt的文件中查找包含关键字"help"的行,并将它们打印到终端。

其它

有时候,AWK命令的形式的部分会有省略,有如下几种情况,举例说明:

1. 只有模式没有动作,结果为显示$0($0 表示整行文本)

awk '/chen/' scores.txt

 2. 只有动作没有模式,就直接执行动作

who | awk '{print $2}'


字段和分隔符

内置变量$1

AWK默认使用空格作为字段分隔符。在处理文本时,它将文本行分割成多个字段,你可以使用$1、$2、$3等特殊的内置变量来引用这些字段($0 表示整行文本),它们用于表示当前正在处理的输入行(或记录)的不同字段(列)的值。例如,$1代表文本中第一个字段,$2代表第二个字段,$n 表示第n个字段,以此类推。

以下是一个示例,演示如何使用AWK命令提取文本行中的第二个字段:

awk '{ print $2 }' english.txt 

如果文本文件中的字段是以逗号、制表符或其他字符分隔的,你可以使用 -F 选项来指定分隔符。例如,如果文本以逗号分隔,您可以这样使用:

awk -F, '{ print $2 }' english.txt 

内置变量FS & OFS

 AWK 命令中,用于控制字段的输入和输出分隔符的内置变量:

  • 输入分隔符 FS (Field Separator):用于指定字段的输入分隔符。默认情况下,awk 使用空格作为字段分隔符,但你可以使用 -F 选项或在 BEGIN 块中设置 FS 来指定不同的字段分隔符。
  • 输出分隔符 OFS (Output Field Separator):用于指定字段的输出分隔符。默认情况下,OFS 为空格,这意味着 awk 在打印输出时会在字段之间插入空格。你可以在 BEGIN 块中设置 OFS 来指定不同的输出字段分隔符。

示例 1

以下是一个示例,演示了如何在 awk 中使用 FS 和 OFS 来控制字段分隔和输出分隔:

假设有一个 CSV 文件 data.csv 包含以下内容:

Alice,90,88,92
Bob,78,85,80
Charlie,92,94,89

可以使用以下 awk 命令来读取该文件,将逗号作为字段分隔符,并在输出中使用制表符作为字段分隔符:

awk 'BEGIN {FS = ","OFS = "\t"  # 使用制表符作为输出字段分隔符
}
{print $1, $2, $3, $4
}' data.csv

 命令也可以这样写入(注意:在 AWK 中,可以在同一行上包含多个命令,并使用分号来分隔它们)

awk 'BEGIN { FS = ","; OFS = "\t" } { print $1, $2, $3, $4 }' data.csv

运行此命令将输出以下内容:

在这个示例中,BEGIN 块中设置了 FS 为逗号,表示字段分隔符是逗号。然后,OFS 被设置为制表符,表示输出字段分隔符是制表符。这样,在输出时字段之间将使用制表符分隔。

示例 2

 OFS 设置为逗号,输出重定向到csv文件

awk -F: 'OFS=","{print $1,$3,$5}' /etc/passwd > passwd.csv

运行此命令将输出以下内容:


内置变量

AWK还提供了一些内置变量,用于执行更复杂的操作:

  • NR:代表记录号(行号),用于跟踪处理的行数。
  • NF:代表字段数,用于确定每行有多少个字段。
  • FS:代表字段分隔符,用于指定字段之间的分隔符。
  • RS:代表记录分隔符,用于指定记录之间的分隔符。

以下是一个示例,演示如何使用这些内置变量来执行操作:

示例1:

awk '{ if (NF > 16) print NR, $1, $NF }' english.txt 

这将打印出那些包含16个或更多字段的行的:行号NR、第一个字段$1和最后一个字段$NF。

示例2:

awk 'NR >= 3 && NR <= 5{print NR,$0}' /etc/passwd

这个命令会打印第三到第五行的内容。使用 NR(行号)内置变量来检查每一行的行号。NR >= 3 表示行号大于等于3,NR <= 5 表示行号小于等于5。

也可以写成下面这种形式,作用结果相同。因为在 AWK 中,逗号“ , ”用于表示一个范围,其中 NR==3,NR==5 表示从行号 3 到行号 5 的范围。然后,{print NR, $0} 用于打印匹配范围内的行号和整个行内容。

awk 'NR==3,NR==5{print NR,$0}' /etc/passwd

AWK 操作符

AWK 是一种强大的文本处理工具,支持各种操作符,用于执行条件检查、数学运算、字符串处理和模式匹配等操作。以下是一些常见的 AWK 操作符及其示例:

算术操作符

  • +:加法操作。
  • -:减法操作。
  • *:乘法操作。
  • /:除法操作。
  • %:取模操作。

示例:这个命令计算每行中的第一个字段和第二个字段的和,并将结果打印出来。

awk '{ result = $1 + $2; print result }' data.txt

关系操作符

  • ==:相等。
  • !=:不相等。
  • <:小于。
  • >:大于。
  • <=:小于等于。
  • >=:大于等于。

示例:这个命令检查第三个字段是否等于 1001,如果是,则打印相应行的第一个字段。

awk '$3 == 1001 { print $1 }' data.txt

逻辑操作符

  • &&:逻辑与。
  • ||:逻辑或。
  • !:逻辑非。

示例:这个命令检查第二个字段是否大于 50 ,并且第三个字段是否小于 90,如果满足条件,则打印相应行的第一个字段。

awk '$2 > 50 && $3 < 90 { print $1 }' data.txt

赋值操作符

  • =:赋值操作。

示例:这个命令计算每行中的第一个字段和第二个字段的和,并将结果赋值给变量 total,然后打印出总和。

awk '{ total = $1 + $2; print "Total: " total }' data.txt

增量/减量操作符

  • ++:增量操作。
  • --:减量操作。

示例:这个命令用于计算文件中的总行数。每次处理一行时,会将变量 count 增加 1。在处理结束时(END 部分),打印总行数。

awk '{ count++; } END { print "Total Lines: " count }' data.txt

模式匹配操作符:

  • ~:匹配模式。
  • !~:不匹配模式。

示例:这个命令匹配第四个字段是否包含特定模式(在示例中是 "pattern")。如果匹配成功,则打印相应行的第一个字段。

awk '$4 ~ /pattern/ { print $1 }' data.txt

字符串连接操作符

  • "":用于连接字符串。

示例:这个命令将每行的第一个字段 $1和第二个字段 $2连接起来,形成完整的姓名,并打印出来。

awk '{ fullName = $1 " " $2; print "Full Name: " fullName }' data.txt

三元条件操作符

  • ? ::用于条件赋值。

示例:这个命令根据第三个字段的值是否大于等于 90 来确定考试状态。如果条件成立,将 "Pass" 赋给变量 status,否则赋给 "Fail",然后打印学生的姓名和状态。

awk '{ status = ($3 >= 90) ? "Pass" : "Fail"; print $1, status }' data.txt

其他应用

AWK不仅支持基本的文本处理,还可以进行其他的一些数据操作,如计算、条件语句、循环等。以下是一些应用的示例:

awk命令的引用shell变量

在 AWK 命令中引用 shell 变量可以通过 -v 选项来实现。这允许您将 shell 变量传递给 AWK 脚本,并在脚本内部使用。

下面是一个示例,演示了如何引用 shell 变量:

# 在 shell 中定义一个变量
name="John" # 使用 AWK 命令引用 shell 变量
awk -v new_name="$name" '{ print new_name }' file.txt

在这个示例中,首先在 shell 中定义了一个名为 name 的变量,并将其值设置为 "John"。然后,通过 -v 选项将 shell 变量 name 传递给了 AWK 脚本 ($ 符号用于引用 shell 变量,获取变量的值),并将其存储在 AWK 变量 name 中。在 AWK 脚本内部,我们使用 new_name 变量来引用 shell 变量的值,然后在 AWK 脚本内部使用 new_name 变量来打印相应行的值。

这样,您可以将 shell 变量的值传递给 AWK 脚本,以在 AWK 脚本中使用它们,实现更灵活的文本处理和数据操作。

补充

需注意区分以下两个命令的区别: 

awk -v name=John '{ print name }' file.txt

和 

name="John" # 定义shell变量name
awk -v new_name="$name" '{print new_name}' file.txt

这两个命令中,主要区别在于name=John和new_name="$name"这两行的定义和传递方式。

第一个命令在AWK命令行中直接定义了一个AWK变量name,并将其值设置为"John"。然后,在AWK脚本内部,直接使用name变量,不需要双引号。

第二个命令首先在shell中定义了一个shell变量name,并将其值设置为"John"。然后,使用-v选项将shell变量name的值传递给了AWK脚本,并将其存储在AWK变量new_name中。

关于双引号的问题:

new_name="$name" 中的双引号用于将shell变量$name的值传递给new_name,以确保如果name包含空格或特殊字符时,值仍然保持完整。在AWK脚本内,如果直接使用name而不是"$name",如果name包含空格或特殊字符,可能会导致意外的结果。所以,使用双引号是一种良好的做法,以确保变量值的完整性。

条件语句

awk '{ if ($2 > 50) print $1, "Pass"; else print $1, "Fail" }' scores.txt

这将根据第二个字段的值决定学生是否通过。

scores.txt文件内容:

循环

awk '{ for (i=1; i<=NF; i++) print $i }' english.txt

这将遍历每一行的字段并打印它们。


总结

AWK命令是Linux中一个功能强大的文本处理工具,它可以处理文本文件的各种任务,包括搜索、提取、转换和报告生成。通过了解基本用法、字段和分隔符、内置变量以及高级功能,您可以更高效地处理文本数据。无论您是在日常系统管理中还是在数据分析中,AWK都是一个有用的工具,值得掌握。希望本文能够帮助您更深入地了解AWK命令并提高您的文本处理技能。

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

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

相关文章

【多线程进阶】常见的锁策略

文章目录 前言1. 乐观锁 vs 悲观锁2. 轻量级锁 vs 重量级锁3. 自旋锁 vs 挂起等待锁4. 读写锁 vs 互斥锁5. 公平锁 vs 非公平锁6. 可重入锁 vs 不可重入锁总结 前言 本章节所讲解的锁策略不仅仅是局限于 Java . 任何和 “锁” 相关的话题, 都可能会涉及到以下内容. 这些特性主…

如何初始化一个vue项目

如何初始化一个vue项目 安装 vue-cli 后 ,终端执行 vue ui npm install vue-cli --save-devCLI 服务 | Vue CLI (vuejs.org) 等一段时间后 。。。 进入项目仪表盘 设置其他模块 项目构建后目录 vue.config.js 文件相关配置 官方vue.config.js 参考文档 https://cli.vuejs.o…

Linux基础指令(六)

目录 前言1. man 指令2. date 指令3. cal 指令4. bc 指令5. uname 指令结语&#xff1a; 前言 欢迎各位伙伴来到学习 Linux 指令的 第六天&#xff01;&#xff01;&#xff01; 在上一篇文章 Linux基本指令(五) 中&#xff0c;我们通过一段故事线&#xff0c;带大家感性的了…

BI神器Power Query(26)-- 使用PQ实现表格多列转换(2/3)

实例需求&#xff1a;原始表格包含多列属性数据,现在需要将不同属性分列展示在不同的行中&#xff0c;att1、att3、att5为一组&#xff0c;att2、att3、att6为另一组&#xff0c;数据如下所示。 更新表格数据 原始数据表&#xff1a; Col1Col2Att1Att2Att3Att4Att5Att6AAADD…

通过containerd部署k8s集群环境及初始化时部分报错解决

目录 一.基础环境配置&#xff08;每个节点都做&#xff09; 1.hosts解析 2.防火墙和selinux 3.安装基本软件并配置时间同步 4.禁用swap分区 5.更改内核参数 6.配置ipvs 7.k8s下载 &#xff08;1&#xff09;配置镜像下载相关软件 &#xff08;2&#xff09;配置kube…

8.3Jmeter使用json提取器提取数组值并循环(循环控制器)遍历使用

Jmeter使用json提取器提取数组值并循环遍历使用 响应返回值例如&#xff1a; {"code":0,"data":{"totalCount":11,"pageSize":100,"totalPage":1,"currPage":1,"list":[{"structuredId":&q…

nodejs+vue健身服务应用elementui

第三章 系统分析 10 3.1需求分析 10 3.2可行性分析 10 3.2.1技术可行性&#xff1a;技术背景 10 3.2.2经济可行性 11 3.2.3操作可行性&#xff1a; 11 3.3性能分析 11 3.4系统操作流程 12 3.4.1管理员登录流程 12 3.4.2信息添加流程 12 3.4.3信息删除流程 13 第四章 系统设计与…

使用docker完成minio服务部署扩容备份迁移生产实践文档

一、minio服务扩容方案 当服务器存储空间不足的时候&#xff0c;需要进行扩容&#xff0c;扩容过程中需要短暂停机时间&#xff0c;预计在一小时内能够完成和恢复 统一注意事项 强烈建议为部署中的所有节点选择基本相似的硬件配置。确保硬件&#xff08;CPU、内存、主板、存…

什么是物联网智慧公厕?

在当今科技快速发展的背景下&#xff0c;具备全感知、可靠传输、智能处理三大特点的物联网技术&#xff0c;正逐渐渗透到各个领域。而智慧公厕作为其中的一个创新应用&#xff0c;正逐渐受到市场的关注和重视。 什么是物联网智慧公厕&#xff1f;物联网智慧公厕是指通过物联网…

SmartX 边缘计算解决方案:简单稳定,支持各类应用负载

在《一文了解近端边缘 IT 基础架构技术需求》文章中&#xff0c;我们为大家分析了边缘应用对 IT 基础架构的技术要求&#xff0c;以及为什么超融合架构是支持边缘场景的最佳选择。值得一提的是&#xff0c;IDC 近日发布的《中国软件定义存储&#xff08;SDS&#xff09;及超融合…

Eclipse 主网即将上线迎空投预期,Zepoch 节点或成受益者?

目前&#xff0c;Zepoch节点空投页面中&#xff0c;模块化Layer2 Rollup项目Eclipse出现在其空投列表中。 配合近期Eclipse宣布了其将由SVM提供支持的Layer2主网架构&#xff0c;并将在今年年底上线主网的消息后&#xff0c;不免引发两点猜测&#xff1a;一个是Eclipse或将在不…

【数据代理+事件处理+计算属性与监视+绑定样式+条件渲染】

数据代理事件处理计算属性与监视绑定样式条件渲染 1 数据代理1.1 回顾Object.defineProperty方法1.2 数据代理 2 事件处理2.1 绑定监听2.2 事件修饰符2.3 键盘事件 3 计算属性与监视3.1 计算属性3.2 监视属性(侦视属性)3.3 watch对比computed 4 绑定样式4.1 绑定class样式4.2 绑…

[尚硅谷React笔记]——第2章 React面向组件编程

目录&#xff1a; 基本理解和使用&#xff1a; 使用React开发者工具调试函数式组件复习类的基本知识类式组件组件三大核心属性1: state 复习类中方法this指向&#xff1a; 复习bind函数&#xff1a;解决changeWeather中this指向问题&#xff1a;一般写法&#xff1a;state.htm…

进程之间的通信方式(共享存储,消息传递,管道通信)

进程通信 进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是指两个进程之间产生数据交互。进程是分配系统资源的单位(包括内存地址空间)&#xff0c;因此各进程拥有的内存地址空间相互独立。为了保证安全&#xff0c;一个进程不能直接访问另一…

前端开发和后端开发的一些建议

前端开发和后端开发是Web开发的两个方向 前端开发主要负责实现用户在浏览器上看到的界面和交互体验&#xff0c;包括HTML、CSS和JavaScript等技术。后端开发主要负责处理服务器端的逻辑和数据&#xff0c;包括数据库操作、服务器配置和接口开发等技术。 前端开发 前端开发需…

Python-Flask:编写自动化连接demo脚本:v1.0.0

主函数&#xff1a; # _*_ Coding : UTF-8 _*_ # Time : 13:14 # Author : YYZ # File : Flask # Project : Python_Project_爬虫 import jsonfrom flask import Flask,request,jsonify import sshapi Flask(__name__)# methods: 指定请求方式 接口解析参数host host_info[…

产品经理如何科学的进行需求调研?

导语&#xff1a;作为产品经理&#xff0c;需求调研是开展工作的重要环节之一。科学、有效地进行需求调研不仅可以帮助产品经理更好地了解用户需求&#xff0c;还能指导产品设计和功能开发&#xff0c;提升产品的竞争力。本文将介绍几种科学的方法和技巧&#xff0c;帮助产品经…

【接口技术】总线课堂习题

1&#xff1a;CPU在执行OUT DX, AL指令时&#xff0c;&#xff08;&#xff09;寄存器的内容送到地址总线上 A&#xff0c;DL B&#xff0c;DX C&#xff0c;AX D&#xff0c;DL 解答&#xff1a;B out指令是把AL的数据输出到DX的端口&#xff0c;因此AL寄存器的内容送到…

C++17中std::filesystem::directory_entry的使用

C17引入了std::filesystem库(文件系统库, filesystem library)。这里整理下std::filesystem::directory_entry的使用。 std::filesystem::directory_entry&#xff0c;目录项&#xff0c;获取文件属性。此directory_entry类主要用法包括&#xff1a; (1).构造函数、…

虚拟车衣VR云展厅平台扩大了展览的触达范围

传统展厅主要是以静态陈列的形式来传达内容&#xff0c;主要的展示形式有图片、视频等&#xff0c;具有一定的局限性&#xff0c;体验感较差&#xff0c;客户往往不能深入地了解信息和细节内容。 VR全景看车是通过虚拟现实技术实现逼真的汽车观赏和试乘体验。消费者可以通过智能…