linux命令awk使用

awk是一条命令,也可以说是一种编程语言, 数据来源可以来自stdin,一个或多个文件。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。

本文默认你有一门编程语言的基础,如js, c\c++, php

文章目录

  • 一、入门
    • awk脚本基本结构
  • 二、使用脚本文件
  • 三、特殊字符的输出
  • 四、内置变量
    • 1. $0示例
    • 2. $n示例
    • 3. FS
    • 4. NF
    • 5. NR
    • 6. OFS
    • 7. ORS
    • 8. RS
    • 9. OFMT
    • 你真的会了吗
    • 总结
      • 4.1 数据变量
      • 4.2 控制变脸
      • 4.3 输出格式变量
  • 五、数学运算
    • 5.1 算术运算符
    • 5.2 赋值运算符
  • 六、条件判断
    • 6.1 比较运算符
    • 6.2 逻辑运算符
    • 6.3 正则表达式
  • 七、其它运算符
    • 7.1 三目运算符
    • 7.2 空格连接符
  • 八、跳过后面指令
  • 参考

一、入门

从stdin读取数据

echo 123 | awk '{print}'

{} 是一个循环的语法,循环文件中的每一行,使用print默认打印每一行。

以下是test.txt文件的内容

123
456
789
awk '{print}' test.txt

输出

123
456
789

打印字符串

awk '{print "hello world"}' test.txt# 输出
hello
hello
hello

如果使用print指令的时候可以指定变量,此时就打印变量的值
以下是传递外部变量的示例

awk '{print a}' a=hello  test.txt# 输出
hello
hello
hello

指定多个变量的值,打印多个变量时使用空格或者字符串隔开

awk '{print a aa aaa}' a=hello aa=" " aaa=world  test.txt# 输出
hello world
hello world
hello world
awk '{print a" "aaa}' a=hello aaa=world  test.txt   # 使用字符串隔开 " "# 输出
hello world
hello world
hello world

awk脚本基本结构

awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file

看起来很复杂的样子,中间的pattern我们就在上面用过

echo 123 | awk '{print}'

上面的 '{print}' 就是pattern

可以发现一共有三个语句块, BEGIN, pattern, END, 每个语句块使用{} 包裹。

  • BEGIN语句块 在读取文件的第一行前被执行
  • pattern语句块, 每读取一行都会执行该语句块
  • END语句块 在读取文件的所有内容后被执行

BEGIN语句块

awk 'BEGIN{print "start"}' test.txt# 输出
start

加上 pattern语句块

awk 'BEGIN{print "start"}{print}' test.txt# 输出
start
123
456
789

加上end语句块

awk 'BEGIN{print "start"}{print}END{print "end"}' test.txt# 输出
start
123
456
789
end

二、使用脚本文件

使用 -f 来指定脚本文件

比如这条指令

awk 'BEGIN{print "start"}{print}END{print "end"}' test.txt

我们可以将命令行上的脚本写入在文件中执行,写入文件有以下几个好处

  • 命令行简洁
  • 增加脚本可阅读性

test.awk 文件

BEGIN{print "start"}{print}END{print "end"}
awk -f test.awk test.txt# 输出
start
123
456
789
end

也可以这样编写脚本,让脚本有更好的可阅读性。
test.awk

BEGIN{print "start"
}{print
}END{print "end"
}

或者这样

BEGIN{print "start"}{print}END{print "end"}

使用 ; 或者回车来执行多条指令
print指令最后都会使用换行进行输出

{print "hello"print "world"
}
awk '{aaa="hello";print aaa}'

三、特殊字符的输出

\\ \自身
\$ 转义$
\t 制表符
\b 退格符
\r 回车符
\n 换行符
\c 取消换行

四、内置变量

$0  		# 当前处理的文本内容
$n 			# n为数字,表示第n个字段
FILENAME 	# 当前输入文件的名。
FS 			# 字段分隔符(默认是任何空格)。
NF 			# 表示字段数,在执行过程中对应于当前的字段数。
NR 			# 表示记录数,在执行过程中对应于当前的行号。
OFMT 		# 数字的输出格式(默认值是%.6g)。
OFS 		# 输出字段分隔符(默认值是一个空格)。
ORS 		# 输出记录分隔符(默认值是一个换行符)。
RS 			# 记录分隔符(默认是一个换行符)。

修改 test.txt 进行示例

1 2 3
4 5 6
7 8 9

1. $0示例

awk '{print "line ->" $0}' test.txt# 输出
line ->1 2 3
line ->4 5 6
line ->7 8 9

2. $n示例

awk '{print "line ->" $1}' test.txt# 输出
line ->1
line ->4
line ->7
awk '{print "line ->" $2}' test.txt# 输出
line ->2
line ->5
line ->8
awk '{print "line ->" $3}' test.txt   # 这条命令是什么聪明的同学们应该已经会抢答了

3. FS

FS 是分割符,是任意多的空白字符,使用正则就是\s*
修改 test.txt

1 2		3
4	5         6
7  8  9
awk '{print $1 " <-> " $3}' test.txt# 输出
1 <-> 3
4 <-> 6
7 <-> 9

很厉害有木有。即使空格不一致也能精准的获取我们想要的列

如果我们修改FS会发生什么呢,这里先修改 test.txt 文件

1:2:3:4
5:6:7:8

将FS修改为:

awk 'BEGIN{FS=":"}{print "第一列->"$1 " | 第二列->" $2}' test.txt# 输出
第一列->1 | 第二列->2
第一列->5 | 第二列->6

此时判断列的分割符就变了

使用 -F 参数能达到和FS变量一样的效果
test.sh

awk -F ":" '{print "第一列->"$1 " | 第二列->" $2}' test.txt

4. NF

NF就是记录的列数,这个多少列就是看使用FS分割符分割当前行时有多少列
修改 test.txt

1 2 3
4 5 6 7
8 9 10 11 12 13
awk '{print "第一行有 " NF " 列"}' test.txt# 输出
第一行有 3 列
第一行有 4 列
第一行有 6

也可以配合 $n来获取最后一列

awk '{print $NF}' test.txt# 输出
3
7
13

5. NR

当前操作的是哪一行

test.txt

123
456
789
awk '{print "这是第" NR "行"}' test.txt# 输出
这是第1行
这是第2行
这是第3行

6. OFS

输出字段分隔符(默认值是一个空格)
test.txt

1 2 3
4 5 6
7 8 9

使用 , 来表示输出一个字段

awk '{print $1, $2, $3}' test.txt# 输出
1 2 3
4 5 6
7 8 9

以上输出一个字段时默认为一个空格,此时我们修改OFS的值

awk  'BEGIN{OFS=" | "}{print $1,$2,$3}' test.txt# 输出
1 | 2 | 3
4 | 5 | 6
7 | 8 | 9

7. ORS

输出记录分隔符, 默认是换行符

test.txt 文件

第一行 1
第二行 2
第三行 3
awk 'BEGIN{ORS=" <-> "}{print $1}' test.txt# 输出
第一行 <-> 第二行 <-> 第三行 <-> 

8. RS

记录分隔符(默认是一个换行符)

test.txt

123|456|789
awk 'BEGIN{RS="|"}{print}' test.txt# 输出
123
456
789

原本处理文件是以一行为一次处理,现在以|分隔为一次处理

9. OFMT

用于如何输出数字,OFMT 默认的输出格式是 “%.6g”,它表示只输出6位数字

echo 1 | awk '{print 3.123456789;print 111111.89999;}'# 输出
3.12346
111112

可以看到输出是会进行四舍五入的,并且默认只会保存6个数字

该格式化只对数字有用, 对字符串是无效的

echo 1 | awk '{print "111111.89999";}'# 输出
111111.89999

test.txt

3.243243434242 	3.243243434242
3.243243434242 	3.243243434242
awk '{print $1}' test.txt# 输出
3.243243434242
3.243243434242

但是可以使用+号强制转换字符串为数字

awk '{print $1+0}' test.txt# 输出
3.24324
3.24324

其实加号是用来做数字运算的

echo 1 | awk '{print 100+100}'

当然它和其他编程语言一样有其他的数字运算符。而且语法都差不多

下面是一些常见的输出格式示例:

  • %e:以科学计数法表示,例如 “1.23e+03”。
  • %.1e:以科学计数法表示,保留一位小数
  • %.g: 等同与 %.e, 不保留小数的科学计数法
  • %g:自动选择合适的显示方式,可以根据数值大小自动切换为普通表示法或科学计数法。
  • %.1g:将数值四舍五入为整数并输出。

你真的会了吗

思考为什么会这样输出?

test.txt

2003.3.22|2002.1.14|2004.3.22

test.awk

BEGIN{FS=".";RS="|"}
{print $1 "年" $2 "月" $3 "日"}
awk -f test.awk test.txt# 思考为什么会这样输出
2003年3月22日
2002年1月14日
2004年1月22日

总结

$n 输出的是一个字段
$0 输出的是一条记录

4.1 数据变量

数据变量设置的为数据

$0 			# 当前记录
$n 			# 第几个字段
FILENAME 	# 当前输入文件的名。
NF 			# 表示字段数,在执行过程中对应于当前的字段数。
NR 			# 表示记录数,在执行过程中对应于当前的行号。

4.2 控制变脸

数据变量中设置的字符用来控制awk如何识别字段和记录

FS 			# 字段分隔符(默认是任何空格)。
RS 			# 记录分隔符(默认是一个换行符)。

4.3 输出格式变量

输出格式变量用来指示awk应该如何输出字段和记录

OFS 		# 输出字段分隔符(默认值是一个空格)。
ORS 		# 输出记录分隔符(默认值是一个换行符)。
OFMT 		# 数字的输出格式(默认值是%.6g)。

五、数学运算

5.1 算术运算符

运算符描述
+
-
*
/
^
%取余

5.2 赋值运算符

运算符
+=
-=
*=
/=
^=
%=

示例

test.awk

{print "# 赋值运算符会对变量本身进行修改"a = 1print "a = 1 | a=" aa += 1print "a += 1 | a=" aa -= 1print "a -= 1 | a=" aa *= 10print "a *= 10 | a=" aa /= 2print "a /= 2 | a=" aa %= 3print "a %= 3 | a=" aa ^= 3print "a ^= 3 | a=" aa++print "a++ | a=" aa--print "a-- | a=" aprint "\n--------------------------\n"print "# 算数运算符不会对变量进行修改"print "a+5: " a+5print "a-3: " a-3print "a*2: " a*2print "a/2: " a/2print "a^2: " a^2print "a%3: " a%3
}

运行结果

# 赋值运算符会对变量本身进行修改
a = 1 | a=1
a += 1 | a=2
a -= 1 | a=1
a *= 10 | a=10
a /= 2 | a=5
a %= 3 | a=2
a ^= 3 | a=8
a++ | a=9
a-- | a=8--------------------------# 算数运算符不会对变量进行修改
a+5: 13
a-3: 5
a*2: 16
a/2: 4
a^2: 64
a%3: 2

六、条件判断

在awk中,使用非零0来表示真和假
该布尔值写在{}的前面

test2.txt

0{print "为假不执行"
}       1{print "非0为真"
}       1+5{print "6也是非0"
}
echo 1 | awk -f test2.awk# 输出
非0为真
6也是非0

6.1 比较运算符

运算符描述
>大于
<小于
==等于
!=不等于
>=大于等于
<=小于等于

举例
test2.awk

1 != 1 {print 0
}1 == 1{print 1
}
echo | awk -f test2.awk# 输出
1

6.2 逻辑运算符

运算符描述
||逻辑或,一边条件为真则为真
&&逻辑与,一边为假则为假
!逻辑非,真为假

test2.awk

1 < 0 || 1==1 {print "||"
}1 < 0 && 1==1{print "&&"
}
echo | awk -f test2.awk# 输出
||

可以使用()来调整优先级

!(1==1 && 1<3){print 1
}

6.3 正则表达式

还可以使用正则表达式来进行判断, 正则表达式使用 // 包裹

判断字符串是否包含hello

test2.awk

"hhhh! hello world!" ~ /hello/{print 1
}
echo | awk -f test2.awk# 输出
1
运算符描述
~匹配该正则表达式
!~不匹配该正则表达式

不输出开头有 total的行

ls -l | awk '{if($0 !~ /^total/){print $0}}'

这里使用了if语句
该语句的结构为

if(条件){指令}

以下是正则表达式的语法

^ 		行首
$ 		行尾
. 		除了换行符以外的任意单个字符
* 		前导字符的零个或多个
.* 		所有字符
[] 		字符组内的任一字符
[^]		对字符组内的每个字符取反(不匹配字符组内的每个字符)
^[^] 	非字符组内的字符开头的行
[a-z] 	小写字母
[A-Z] 	大写字母
[a-Z] 	小写和大写字母
[0-9] 	数字
\< 		单词头单词一般以空格或特殊字符做分隔,连续的字符串被当做单词
\> 		单词尾

七、其它运算符

7.1 三目运算符

echo 1 | awk '{print 1<2 ? "真" : "假"}'# 输出

7.2 空格连接符

字符串使用一个或多个空格连接

print "hello"  "-"   "world"

八、跳过后面指令

next进行下一条记录处理

{next}{print}

此时后面的print不会执行

echo| awk '{print 123}{next}{print 456}'# 输出
123

更多用法在后面进行更新

参考

  • https://wangchujiang.com/linux-command/c/awk.html

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

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

相关文章

Fine-Grained Semantically Aligned Vision-Language Pre-Training细粒度语义对齐的视觉语言预训练

abstract 大规模的视觉语言预训练在广泛的下游任务中显示出令人印象深刻的进展。现有方法主要通过图像和文本的全局表示的相似性或对图像和文本特征的高级跨模态关注来模拟跨模态对齐。然而&#xff0c;他们未能明确学习视觉区域和文本短语之间的细粒度语义对齐&#xff0c;因为…

Java开发环境简介(JDK、JRE、JVM)

目录 1、Java开发环境 2、JDK和JRE 3、JDK下载和安装 3.1 下载 3.2 安装 3.3 配置path环境变量 JDK8配置方案1&#xff1a;只配置path ⭐JDK8配置方案2&#xff1a;配置JAVA_HOMEpath&#xff08;推荐&#xff09; path配置小结 JDK17配置方案&#xff1a;自动配置 …

redis-学习笔记(Jedis 前置知识)

自定义的 Redis 客户端 咱们可以实现编写出一个自定义的 Redis 客户端 因为 Redis 公开了自己使用的自定义协议 ---- RESP 协议清楚了, 那么通信数据格式就清除了, 就能完成各层次之间的数据传输, 就能开发服务器和客户端 RESP — Redis 的 序列化 协议 特点: 简单好实现快读进…

C++友元类,工厂模式和继承的融合案例

//友元没有继承性&#xff0c;没有传递性,所以在animal中定义友元类是无效的class animal{public:animal(){};virtual ~animal(){};};class Cat:public animal{friend class animalFactory;private:Cat(){}private:string m_name;string m_color;public:void about(){cout<&…

独孤思维:白嫖我项目,还这么理直气壮

你在副业圈呆久了&#xff0c;会遇到各种各样&#xff0c;形形色色的人。 昨天有个人突然冒出来&#xff0c;问我绝版书某个细节怎么规避。 我看了和他之前的聊天记录&#xff0c;他是去年加我的&#xff0c;当时加我的时候给他发了一些资料。 这些免费的资料&#xff0c;主…

代码审计中的常见漏洞【一】

预计更新一、代码审计简介 代码审计的定义、作用和流程代码审计的分类和方法论 二、代码审计的准备工作 代码审计前需要了解的基础知识和技能代码审计的工具和环境准备 三、代码审计中的常见漏洞 SQL注入漏洞XSS漏洞CSRF漏洞 4.文件包含漏洞 5.文件上传漏洞 四、代码审计…

AC修炼计划(AtCoder Beginner Contest 332)

传送门&#xff1a;AtCoder Beginner Contest 332 - AtCoder a,b,c都还是很基础了。d题是一个bfs的纯暴力问题。 E - Lucky bag 看看范围&#xff0c;n15&#xff0c;第一个想法是dfs纯暴力&#xff0c;但所有的情况太大&#xff0c;各种决策层出不穷&#xff0c;会t。所以转…

VM实现方式及其优缺点

在众多VM实现方式中&#xff0c;我可以说几种常见的实现方式。例如&#xff0c;基于栈的方式、基于寄存器的方式、基于堆的方式等。下面我将分别对这几种方式进行阐述&#xff0c;并讨论它们各自的优点和缺点&#xff0c;以及它们各自的应用场景。 基于栈的方式 基于栈的方式…

Lightweight Directory Access Protocol (LDAP 轻量级目录访问协议)

The Lightweight Directory Access Protocol (LDAP /ˈɛldp/) is an open, vendor-neutral, industry standard application protocol for accessing and maintaining distributed directory information services over an Internet Protocol (IP) network.[1] Directory serv…

RocketMQ可视化工具 打包遇到的yarn intall 问题

文章目录 RocketMQ可视化工具1.github上下载2.修改参数3.运行4.打包5.出错6.解决7.重试8.再解决9.很奇怪运行没错&#xff0c;但是测试错啦10.不想深究&#xff0c;直接跳过测试11.展示成功 RocketMQ可视化工具 1.github上下载 下载地址 https://github.com/apache/rocketmq-…

基于Hadoop的电商数据分析系统设计与实现

基于Hadoop的电商数据分析系统设计与实现 Design and Implementation of E-commerce Data Analysis System based on Hadoop 目录 目录 2 摘要 3 关键词 3 第一章 绪论 4 1.1 研究背景 4 1.2 研究目的与意义 5 1.3 现有研究综述 6 第二章 Hadoop技术介绍 8 2.1 Hadoop概述 8 2.…

redis:二、缓存击穿的定义、解决方案(互斥锁、逻辑过期)的优缺点和适用场景、面试回答模板

缓存击穿的定义 缓存击穿是一种现象&#xff0c;具体就是某一个数据过期时&#xff0c;恰好有大量的并发请求过来&#xff0c;这些并发的请求可能会瞬间把DB压垮。典型场景就是双十一等抢购活动中&#xff0c;首页广告页面的数据过期&#xff0c;此时刚好大量用户进行请求&…

protobuf、protobuf-c、protobuf-c-rpc在Linux(Ubuntu18.04)编译安装及交叉编译arm\aarch64版本

protobuf、protobuf-c、protobuf-c-rpc在Linux&#xff08;Ubuntu18.04&#xff09;编译安装及交叉编译arm\aarch64版本 文章目录 protobuf、protobuf-c、protobuf-c-rpc在Linux&#xff08;Ubuntu18.04&#xff09;编译安装及交叉编译arm\aarch64版本一、前言二、protobuf、rp…

Unity 置顶OpenFileDialog文件选择框

置顶文件选择框 &#x1f32d;处理前&#x1f959;处理后 &#x1f32d;处理前 &#x1f959;处理后 解决方案

【TI毫米波雷达入门-10】TI毫米波速度检测思路

知识回顾 FMCW chirp 雷达收发流程 中频信号 傅里叶变换 多目标检测 距离分辨率 最大距离 公式总结 FMCW数据处理流程示例 两个维度看图表 从range维度&#xff0c;水平方向上&#xff0c;反映每个chirp 发出的FMCW被接收天线检测到&#xff0c;2个点的目标&#xff0c;对应两个…

滑动窗口如人生,回顾往事不复还———力扣刷题

第一题&#xff1a;长度最小的子数组 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 思路&#xff1a; 第一想法肯定时暴力枚举&#xff0c;枚举数组任何一个元素&#xff0c;把他当起始位置&#xff0c;然后从起始位置找最短区间&#xff0c;使得…

uniapp原生插件之安卓app添加到其他应用打开原生插件

插件介绍 安卓app添加到其他应用打开原生插件&#xff0c;接收分享的文本和文件&#xff0c;支持获取和清空剪切板内容 插件地址 安卓app添加到其他应用打开原生插件&#xff0c;支持获取剪切板内容 - DCloud 插件市场 超级福利 uniapp 插件购买超级福利 详细使用文档 u…

Nyquist Theorem(取样定理)

取样定理&#xff0c;又称为奈奎斯特定理&#xff08;Nyquist Theorem&#xff09;&#xff0c;是信号处理领域中一项至关重要的基本原理。它规定了对于连续时间信号&#xff0c;为了能够完全准确地还原出原始信号&#xff0c;即使是在离散时间下进行采样和再构建&#xff0c;都…

Mybatis-plus更新多张表,保证事务安全的情况下使用异步多线程实现(待验证)

Mybatis-plus更新多张表,保证事务安全的情况下使用异步多线程实现(待验证) 文章目录 Mybatis-plus更新多张表,保证事务安全的情况下使用异步多线程实现(待验证)方案一:方案二:方案三:使用mybatis-plus更新数据库的五张不同的表,开启五个线程&#xff0c;每个线程负责更新一张表…

【JUC】二十七、synchronized锁升级之无锁

文章目录 1、背景2、Monitor、Java对象、线程如何关联起来的&#xff1f;3、synchronized锁升级4、锁升级之无锁 关于synchronized同步&#xff0c;能用无锁结构就不要用锁&#xff1b;能锁块&#xff0c;就不要锁整个方法&#xff1b;能用对象锁&#xff0c;就不要用类锁。 用…