【Linux】gawk编辑器二

一、变量

gawk编程语言支持两种变量:内建变量和自定义变量。

1、内建变量

gawk使用内建变量来引用一些特殊的功能。

字段和记录分隔符变量

数据字段变量

此变量允许使用美元符号($)和字段在记录中的位置值来引用对应的字段。要引用记录中的第一个数据字段,就用变量 $1,要引用第二个数据字段,就用变量 $2,以此类推。

数据字段由字段分隔符划定。默认情况下,字段分隔符是一个空白字符:空格制表符。可以通过使用命令行选项 -F ,或者使用特殊的内建变量 FS 修改字段分隔符。

gawk数据字段和记录变量
FIELDWIDTHS由空格分隔的一列数字,定义了每个数据字段的确切宽度
FS输入字段分隔符
RS输入记录分隔符
OFS输出字段分隔符
ORS输出记录分隔符

 默认情况下,gawk会将OFS变量的值设置为一个空格。print命令会自动将OFS变量的值置于输出的每个字段之间。

gawk 'BEGIN{FS=","} {print $1,$2,$3}' test2.txt

可以通过设置0FS变量,可以在输出中用任意字符串来分隔字段。

gawk 'BEGIN{FS=","; OFS="*"} {print $1,$2,$3}' test2.txt

 FIELDWIDTHS变量可以不通过字段分隔符读取记录。一旦设置了此变量,gawk就会忽略FS变量,并根据提供的字段宽度计算字段。

gawk 'BEGIN{FIELDWIDTHS="2 4 5 3"} {print $1,$2,$3,$4}' test3.txt

变量RSORS定义了gawk对数据流中记录的处理方式。默认情况下,gawk会将RS和ORS设置为换行符。

默认的RS值表明,输入数据流中的每行文本就是一条记录。

 包含地址和电话号码的数据中,占据了多行

可以把FS变量设置成换行符,这样就表明数据流中的每一行都是一个单独的字段,行内的所有数据都属于同一个数据字段。同时把RS变量设置成空字符串,然后在数据记录之间留一个空行。gawk就会把每一个空行视为记录分隔符。

 gawk 'BEGIN{FS="\n"; RS=""} {print $1,$3}' test3.txt

gawk将文件中的每一行都视为一个字段,同时将空行作为记录分隔符。 

 数据变量

ENVIRON变量使用关联数组来提取shell环境变量,其中关联数组用文本而非数值作为数组索引。

如下所示,可以用这种方法从shell中提取任何环境变量的值,以供gawk脚本使用。

gawk '
BEGIN{
print ENVIRON["HOME"]
print ENVIRON["PATH"]
}'

 变量FNR、NF和NR用于在gawk脚本中跟踪数据字段和记录。

变量NF可以让用户在不知道具体位置的情况下引用记录中的最后一个数据字段。NF变量含有数据文件中的最后一个字段的编号,在其前面加上美元符号,就把它用作字段变量。

gawk 'BEGIN{FS=":" ; OFS=":"} {print $1,$NF}' /etc/passwdgawk 'BEGIN{FS=":" ; OFS=":"} {$NF}' /etc/passwd

注意看执行两条命令后打印出来的区别之处。 

 FNR变量包含当前数据文件中已处理过的记录数,NR变量包含已处理过的记录总数。

gawk 'BEGIN{FS=","}{print $1, "FNR="FNR}' test2.txt test2.txt

上述gawk脚本在命令行中指定了两个输入文件(都是test2.txt),此脚本会打印第一个字段和FNR变量的当前值。 

gawk 'BEGIN{FS=","}{print $1, "FNR="FNR, "NR="NR}
END{print "这儿总共有",NR,"条记录被处理了"}'' test2.txt test2.txt

 在gawk处理第二个数据文件时,FNR变量的值被重置了,而NR变量则继续计数。

 因此,如果只使用一个数据文件作为输入,那么FNR和NR的值是相同的;如果使用多个数据文件作为输入,那么FNR的值会在处理每个数据文件时被重置,NR的值则会继续计数直到处理完所有的数据文件。

 2、自定义变量

gawk自定义变量的名称由任意数量的字母、数字和下划线组成,但不能以数字开头。而且,其变量名区分大小写

在脚本中给变量赋值

在gawk脚本中给变量赋值与给shell脚本中的变量赋值一样,都使用赋值语句。

gawk '
BEGIN{
test1="测试……"
print test1
}'

 也可以保存数值或文本值:

gawk '
BEGIN{
test1="测试……"
print test1
test1=89
print test1
}'

还可以处理数学算式:

gawk 'BEGIN{x=7; x=x *9 + 10; print x}'

 在命令行中给变量赋值

可以在不修改脚本代码的情况下改变脚本的行为。

BEGIN{FS=","}
{print $n}
gawk -f test.sh n=3 test2.txt

 通过上述命令,可以显示文件中的第3个字段(n=3)。

使用命令行参数来定义变量值会产生一个问题:在设置过变量之后,这个值在脚本的BEGIN部分不可用

BEGIN{print "开始值是",n; FS=","}
{print $n}
gawk -f test.sh n=3 test2.txt

使用 -v 选项解决该问题,它允许在BEGIN部分之前设定变量。它必须放在脚本代码之前。

gawk -v n=3 -f test.sh test2.txt

 二、数组

gawk使用关联数组来提供数组的功能。与数字型数组不同,关联数组的索引可以是任意文本字符串,它用各种字符串来引用数组元素,每个索引字符串都必须能够唯一地标识出分配给它的数组元素。就跟其它语言中的哈希表、字典类似。

1、定义数组变量

使用标准赋值语句定义数组变量。

格式:var[index] = element

var:变量名;index:关联数组的索引值;element:数组元素值

gawk 'BEGIN{
capital["中国"] = "北京"
print capital["中国"]
}'

 2、遍历数组变量

在gawk脚本中遍历关联数组,使用for语句的一种特殊形式。

for {var in array}

{

 statements

}

此for语句会在每次循环时将关联数组array的下一个索引值赋给变量var,然后执行一遍statements。变量var中存储的是索引而不是数组元素值。

gawk 'BEGIN{
var["a"] = 10
var["h"] = 190
var["k"] = 78
var["t"] = "hello"
for (test in var)
{print "索引:",test," - 值:", var[test]
}
}'

如下所示,索引值没有固定的返回顺序。 

3、删除数组变量

 从关联数组中删除数组元素要使用一个特殊的命令:

delete array[index]

delete命令会从关联数组中删除索引值及其相关的数组元素值。

gawk 'BEGIN{
var["a"] = 10
var["h"] = 190
var["k"] = 78
var["t"] = "hello"
for (test in var)
{print "索引:",test," - 值:", var[test]
}delete var["k"]
print "*****"
for (test in var)
{ print "索引:",test," - 值:", var[test]
}
}'

三、使用模式

 gawk支持几种类型的匹配模式来过滤数据记录。比如,关键字BEGINEND可以在读取数据流之前或之后执行命令的特殊模式。

1、正则表达式

可以使用基础正则表达式(BRE)或扩展正则表达式(ERE)来筛选数据。

在使用正则表达式时,它必须出现在与其对应脚本的左花括号前。

# 匹配含有字符串“11”的数据
gawk 'BEGIN{FS=","} /11/{print $1}' test2.txt

#匹配用作字段分隔符的逗号
gawk 'BEGIN{FS=","} /,d/ {print $1}' test2.txt

2、匹配操作符

 匹配操作符(~)是一个很强大的工具,可以将正则表达式限制在记录的特定数据字段。可以指定匹配操作符、数据字段变量以及要匹配的正则表达式。

$1 ~ /^data/:此表达式会过滤出第一个数据字段以data开头的所有记录。

gawk 'BEGIN{FS=","} $2 ~ /^data3/{print $0}' test2.txt

匹配第2个数据字段要以“data3”开头的数据。 

可以用它在文件中搜索特定的数据元素。

gawk -F: '$1 ~ /csb/{print $1, $NF}' /etc/passwd

上面的脚本命令会在第一个数据字段中查找文本“csb”,如果匹配成功,则打印出第一个数据字段和最后一个数据字段。 

 也可以使用 ! 符号来排除正则表达式的匹配:

$1 !~ /expression/

gawk -F: '$1 !~ /^csb/{print $1,$NF}' /etc/passwd

匹配第一个数据字段不是以“csb”开头的数据, 如果匹配成功,则打印出第一个数据字段和最后一个数据字段。

3、数学表达式

显示出所有属于root用户组(组ID为0)的用户。

下面的gawk脚本会检查记录中值为0的第四个字段。 

gawk -F: '$4 == 0{print $1}' /etc/passwd

 也可以对文本数据使用表达式,但跟正则表达式不同,表达式必须完全匹配。

gawk -F, '$1 == "data"{print $1}' test2.txtgawk -F, '$1 == "data21"{print $1}' test2.txt

四、结构化命令

 1、if 语句

gawk编程语言支持标准格式的 if-then-else 语句。

gawk '{
if ($1 > 30)
{x = $1 * 2print x
}
}' test3.txt

gawk '{
if ($1 < 30)
{x = $1 * 2print x
} else
{x = $1 / 2print x
}}' test3.txt

 

 也可以在单行中使用else语句。

gawk '{if ($1 < 30) print $1 * 2; else print $1 / 2}' test3.txt

2、while语句

gawk '{
total = 0
i = 1
while (i <=3)
{total += $ii++
}
avg = total / 3
print "平均值是:", avg
}' test1.txt

还可以使用break语句和continue语句

gawk '{
total = 0
i = 1
while (i <= 3)
{total += $iif (i == 2)breaki++
}
avg = total / 2
print "前两个数据的平均值是:", avg
}' test1.txt 

 

3、do-while语句

do-while语句与while语句类似,但会在检查条件语句之前先执行命令。

gawk '{
total = 0
i = 1
do
{total += $ii++
} while (total < 200)
print total
}' test1.txt 

4、for语句

gawk '{
total = 0
for (i = 1; i <=3; i++)
{total += $i
} 
avg = total /3
print "平均值是:",avg
}' test1.txt 

五、格式化打印

和C语言编程一样,gawk中的格式化打印命令 printf 可以控制如何显示数据

格式:printf "format string, var1, var2

format string是格式化输出的关键,它会用文本元素和格式说明符来具体指定如何呈现格式化输出。格式说明符是一种特殊的代码,可以指明显示什么类型的变量以及如何显示。

1、控制字母

gawk脚本会将每个格式说明符作为占位符,供命令中的每个变量使用。第一个格式说明符对应列出第一个变量,第二个对应第二个变量,以此类推。

格式说明符的控制字母
c将数字作为ASCII字符显示
d显示整数值
i显示整数值
e用科学计数法显示数字
f显示浮点值
g用科学计数法或浮点数显示(较短的格式优先)
o显示八进制值
s显示字符串
x显示十六进制值
X用大写字母显示十六进制值
gawk 'BEGIN{
x = 10 * 10000
printf "结果是:%e\n", x
}'

 2、修饰符

除了控制字母,还有3种修饰符可以进一步控制输出。

width

指定输出字段的最小宽度。如果输出短于这个值,则printf会将文本右对齐,并用空格进行填充。如果输出比指定的宽度长,则按实际长度输出。

prec

指定浮点数中小数点右侧的位数或者字符串中显示的最大字符数。

减号 - 

指明格式化空间中的数据采用左对齐而非右对齐

在同一行中打印多个输出。

gawk 'BEGIN{FS=","} {printf "%s ", $1} END{printf "\n"}' test2.txt

 使用修饰符格式化第一个字符串的值

gawk 'BEGIN{FS="\n"; RS=""} {printf "%10s %s\n", $1, $2}' test1.txt

使用printf处理浮点值 

gawk '{
total = 0
for (i = 1; i <=3; i++)
{total += $i
}
avg = total / 3
printf "平均值是:%8.1f\n",avg
}' test3.txt

%8.1f强制printf命令将浮点值近似到小数点后一位。 

六、内置函数 

gawk编程语言提供了一些内置函数用于执行一些常见的数学、字符串以及时间运算。

1、数学函数

gawk数学函数
atan(x,y)x/y的反正切,x和y以弧度为单位
cos(x)x的余弦,x以弧度为单位
exp(x)x的指数
int(x)x的整数部分,取靠近0一侧的值
log(x)

x的自然对数

rand()比0大且比1小的随机浮点数
sin(x)x的正弦,x以弧度为单位
sqrt(x)

x的平方根

srand(x)为计算随机数指定一个种子值
and(v1,v2)对v1和v2执行按位AND运算
comp1(v1)对v1执行补运算
lshift(val,count)将val左移count位
or(v1,v2)对v1和v2执行按位OR运算
rshift(val,count)将val右移count位
xor(v1,v2)对v1和v2执行按位XOR运算

 产生较大随机整数的常见方法是综合运用rand()函数和int()函数:

x = int(10 * rand())

上述命令会返回一个0~9(包括0和9)的随机整数值。

2、字符串函数

gawk字符串函数
index(s,t)返回字符串t在字符串s中的索引位置;如果没找到,则返回0
length([s])返回字符串s的长度;如果没有指定,则返回$0的长度
match(s,r [,a])返回正则表达式r在字符串s中匹配位置的索引。如果指定了数组a,则将s的匹配部分保存在该数组中
split(s,a [,r])将s以FS(字段分隔符)或正则表达式r(如果有指定的话)分割并放入数组a中。返回分割后的字段总数
sub(r,s [,t])在变量$0或目标字符串t中查找匹配正则表达式r的部分。如果找到了,就用字符串s替换第一处匹配
substr(s,i [,n])返回s中从索引 i 开始、长度为n的子串。如果未提供n,则返回s中剩下的部分
tolower(s)将s中的所有字符都转换成小写
toupper(s)将s中的所有字符都转换成大写
gawk 'BEGIN{x = "ning"; print toupper(x); print length(x)}'

3、时间函数

时间函数多用于处理日志文件。日志文件中一般含有需要进行比较的日期。通过将日期的文本表示形式转换成纪元时(自1970-01-01 00:00:00 UTC到现在的秒数),可以做到很容易就比较日期。

gawk时间函数
mktime(dataspec)将一个按YYYY MM DD HH MM SS [DST]格式指定的日期转换成时间戳
strftime(format [, timestamp])将当前时间的时间戳或timestamp(如果提供了的话)转化成格式化日期(采用shell命令date的格式)
systime()返回当前时间的时间戳
gawk 'BEGIN{
date = systime()
day = strftime("%A, %B %d, %Y", date)
print day
}'

 

七、自定义函数

 可以在gawk脚本中自己创建函数。

1、定义函数

定义自己的函数,必须使用function关键字。

function name([variables])

{  

  statements

}

function myrand(limit)
{  return int(limit * rand())
}

2、使用自定义函数

定义函数时,它必须出现在所有代码块之前(包括BEGIN代码块)。

gawk '
function myrand(limit)
{  return int(limit * rand())
}
BEGIN{x = myrand(8)print x
}'

3、创建函数库

gawk提供了一种方法可以将多个函数放入单个库文件中。

首先,创建一个包含所有gawk函数的文件

# 函数库名:functionlib
function myrand(limit)
{  return int(limit * rand())
}function myprint()
{printf "%-16s - %s\n", $1, $4
}function printthird()
{print $3
}

接着,使用函数库时,只要创建好gawk脚本文件,然后在命令行中同时指定库文件和脚本文件即可。

# gawk脚本名 test
BEGIN{ FS="\n"; RS=""}
{myprint()
}

然后执行下述命令即可。(-f选项不能和内联gawk脚本一起使用,所以要在同一命令行中使用多个 -f 选项。) 

gawk -f functionlib -f test test2.txt

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

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

相关文章

【Linux】Linux入门(三)权限

目录 前提权限概念whoami指令 Linux权限管理文件访问者的分类&#xff08;人&#xff09;file指令权限信息权限的表示方法 chmod指令 更改权限chown指令 修改文件&#xff0c;文件夹所属用户和用户组 权限掩码umask&#xff08;权限掩码&#xff09; 粘滞位 前提 请先看下面这…

Low-Level 大一统:如何使用Diffusion Models完成视频超分、去雨、去雾、降噪等所有Low-Level 任务?

Diffusion Models专栏文章汇总:入门与实战 前言:视频在传输过程中常常因为各种因素(如恶劣天气、噪声、压缩和传感器分辨率限制)而出现质量下降,这会严重影响计算机视觉任务(如目标检测和视频监控)的性能。现有的视频修复方法虽然取得了一些进展,但通常只能针对特定的退…

生产环境中常用的设计模式

生产环境中常用的设计模式 设计模式目的使用场景示例单例模式保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点- 日志记录器- 配置管理器工厂方法模式定义一个创建对象的接口&#xff0c;让子类决定实例化哪个类- 各种工厂类&#xff08;如视频游戏工厂模式创…

点云目标检测训练数据预处理---平面拟合与坐标转换(python实现)

在做centerpoint训练之前&#xff0c;需要先对点云数据进行标注&#xff0c;然后制作kittti数据集。不用nuScenes或者waymo数据集的理由也很简单&#xff0c;因为麻烦&#xff0c;没有kitti数据集直观。 kitti数据集的格式如下&#xff0c;可以看到数据集中只有航向角&#xff…

一文大白话讲清楚webpack基本使用——2——css相关loader的配置和使用

一文大白话讲清楚webpack基本使用——2——css相关loader的配置和使用 1. 建议按文章顺序从头看是看 第一篇&#xff1a;一文大白话讲清楚啥是个webpack第二篇&#xff1a;一文大白话讲清楚webpack基本使用——1——完成webpack的初步构建然后看本篇&#xff0c;Loader的配置…

Python基于OpenCV和PyQt5的人脸识别上课签到系统【附源码】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

2024年第十五届蓝桥杯青少组国赛(c++)真题—快速分解质因数

快速分解质因数 完整题目和在线测评可点击下方链接前往&#xff1a; 快速分解质因数_C_少儿编程题库学习中心-嗨信奥https://www.hixinao.com/tiku/cpp/show-3781.htmlhttps://www.hixinao.com/tiku/cpp/show-3781.html 若如其他赛事真题可自行前往题库中心查找&#xff0c;题…

使用Edge打开visio文件

使用Edge打开visio文件 打开Edge浏览器搜索‘vsdx edge’ 打开第一个搜索结果 Microsoft Support 根据上述打开的页面进行操作 第一步&#xff1a;安装Visio Viewer 第二步&#xff1a;添加注册表 桌面新增文本文件&#xff0c;将下面的内容放入新建文本中&#xff0c;修…

AT8870单通道直流电机驱动芯片

AT8870单通道直流电机驱动芯片 典型应用原理图 描述 AT8870是一款刷式直流电机驱动器&#xff0c;适用于打印机、电器、工业设备以及其他小型机器。两个逻辑输入控制H桥驱动器&#xff0c;该驱动器由四个N-MOS组成&#xff0c;能够以高达3.6A的峰值电流双向控制电机。利用电流…

基础入门-传输加密数据格式编码算法密文存储代码混淆逆向保护安全影响

知识点&#xff1a; 1、传输格式&传输数据-类型&编码&算法 2、密码存储&代码混淆-不可逆&非对称性 一、演示案例-传输格式&传输数据-类型&编码&算法 传输格式 JSON XML WebSockets HTML 二进制 自定义 WebSockets&#xff1a;聊天交互较常…

抽奖系统(4——活动模块)

1. 活动创建 需求回顾 创建的活动信息包含&#xff1a; 活动名称活动描述关联的一批奖品&#xff0c;关联时需要选择奖品等级&#xff08;一等奖、二等奖、三等奖&#xff09;&#xff0c;及奖品库存圈选一批人员参与抽奖 tip&#xff1a;什么时候设置奖品数量和奖品等级&am…

广播网络实验

1 实验内容 1、构建星性拓扑下的广播网络,实现hub各端口的数据广播,验证网络的连通性并测试网络效率 2、构建环形拓扑网络,验证该拓扑下结点广播会产生数据包环路 2 实验流程与结果分析 2.1 实验环境 ubuntu、mininet、xterm、wireshark、iperf 2.2 实验方案与结果分析…

Fabric区块链网络搭建:保姆级图文详解

目录 前言1、项目环境部署1.1 基础开发环境1.2 网络部署 2、后台环境2.1、环境配置2.2、运行springboot项目 3、PC端3.1、安装依赖3.2、修改区块链网络连接地址3.3、启动项目 前言 亲爱的家人们&#xff0c;创作很不容易&#xff0c;若对您有帮助的话&#xff0c;请点赞收藏加…

【AI | pytorch】torch.polar的使用

一、torch.polar的使用 torch.polar 是 PyTorch 中用来生成复数张量的一个函数&#xff0c;但它与数学中的复数表达式 ( z re^{i\theta} ) 是等价的。 具体来说&#xff0c;torch.polar(abs, angle) 接受两个实数张量参数&#xff1a; abs&#xff1a;表示复数的模长&#…

.Net Core微服务入门全纪录(六)——EventBus-事件总线

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…

深度学习 · 手撕 DeepLearning4J ,用Java实现手写数字识别 (附UI效果展示)

引言 随着人工智能技术的不断发展&#xff0c;手写数字识别已经成为深度学习领域的一个经典案例。不管是老牌的机器学习模型还是现代的神经网络架构&#xff0c;手写数字识别总是大家学习和实战的起点之一。而对于我们日常使用的Java开发者来说&#xff0c;借助DeepLearning4J…

linux平台RTMP|RTSP播放器如何回调SEI数据?

我们在对接Linux平台RTMP|RTSP播放的时候&#xff0c;有遇到这样的技术需求&#xff0c;合作企业在做无人机视觉分析场景的时候&#xff0c;除了需要低延迟的拿到解码后的RGB|YUV数据&#xff0c;然后投递给他们自己的视觉算法处理模块外&#xff0c;还需要播放器支持SEI的回调…

vue2 - Day05 - VueX

Vuex 是 Vue.js 官方的状态管理库。它是一个让你能在应用中集中管理共享状态的工具。当应用的规模逐渐增大&#xff0c;组件之间的数据传递变得越来越复杂时&#xff0c;Vuex 就成为了救星&#xff0c;提供了一个集中式的存储来管理所有的组件状态&#xff0c;并且保证状态以一…

Linux系统之kill命令的基本使用

Linux系统之kill命令的基本使用 一、kill命令介绍1. kill命令简介2. kill命令的使用场景3. kill命令使用注意事项 二、kill命令的使用帮助1. 查看kill命令帮助信息2. kill命令帮助解释 三、kill常用的信号1. 列出所有的信号2.kill常用的信号 四、kill命令的基本使用1. 运行一个…

HTML之拜年/跨年APP(改进版)

目录&#xff1a; 一&#xff1a;目录 二&#xff1a;效果 三&#xff1a;页面分析/开发逻辑 1.页面详细分析&#xff1a; 2.开发逻辑&#xff1a; 四&#xff1a;完整代码&#xff08;不多废话&#xff09; index.html部分 app.json部分 二&#xff1a;效果 三&#xff1a;页面…