博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
awk 的内置变量 NF、NR、FNR、FS、OFS、RS、ORS
阅读量:2109 次
发布时间:2019-04-29

本文共 2894 字,大约阅读时间需要 9 分钟。

NF 字段个数,(读取的列数)

NR 记录数(行号),从1开始,新的文件延续上面的计数,新文件不从1开始
FNR 读取文件的记录数(行号),从1开始,新的文件重新从1开始计数
FS 输入字段分隔符,默认是空格
OFS 输出字段分隔符 默认也是空格
RS 输入行分隔符,默认为换行符
ORS 输出行分隔符,默认为换行符

NF

读取记录的字段数(列数),例如:

[root@localhost test]# awk '{print "字段数:" NF}' test字段数:4字段数:4字段数:3字段数:4字段数:4[root@localhost test]# cat testa aa aaa 1b bb bbb 2c cc cccd dd ddd 4e ee eee 5

如上,awk在读取文件时,按行读取,每一行的字段数(列数),赋值给内置变量NF,打印出来的就是每行的字段总数,有以下简单示例:

[root@localhost test]# awk '{print $NF}' test12ccc45t@localhost test]# cat testa aa aaa 1b bb bbb 2c cc cccd dd ddd 4e ee eee 5

我们有需求,只需要最后一列的数据,由于每一行的列数不一,最后一列无法指定固定的列数,可以使用NF来表示列数 $NF 表示打印出等于总列数的那一列的数据,显而易见就是打印最后一列的数据

NR

读取文件的行数(在某些应用场景中可以当作行号来使用)

[root@localhost test]# awk '{print "行号为:" NR}' test行号为:1行号为:2行号为:3行号为:4行号为:5[root@localhost test]# cat testa aa aaa 1b bb bbb 2c cc cccd dd ddd 4e ee eee 5

如上,打印出读取文件的行数,因为是按行读取,在应用场景中,行数可以等同于行号,用来输出对应行的行号,NR 还可以用作判断输出,如下简单例子:

[root@localhost test]# awk '{if(NR>2)print "行号为:" NR }' test行号为:3行号为:4行号为:5

判断当读取的行数(行号)大于2时,输出对应的内容。

FNR

也是读取文件的行数,但是和NR 不同的是当读取的文件有两个或两个以上时,NR 读取完一个文件,行数继续增加 而FNR 重新从1开始记录

[root@localhost test]# awk '{print "NR:" NR "FNR:" FNR}' test test2 test3NR:1FNR:1NR:2FNR:2NR:3FNR:3NR:4FNR:4NR:5FNR:5NR:6FNR:1NR:7FNR:2NR:8FNR:3NR:9FNR:1[root@localhost test]# cat testa aa aaa 1b bb bbb 2c cc cccd dd ddd 4e ee eee 5[root@localhost test]# cat test2! !! !!! 1@ @@ @@@ 2# ## ### 3[root@localhost test]# cat test3bbbbb nnnnn mmmm

如上,总共有三个文件,读取三个文件NR 从一开始一直增加,FNR 每读取到一个新的文件,行数重新从一开始增加,有一个有趣的应用,比较两个文件A,B是否一致,以A作为参考,不一致的输出行号

[root@localhost test]# awk '{if(NR==FNR){arry[NR]=$0}else{if(arry[FNR]!=$0){print FNR}}}' test test13[root@localhost test]# cat testa aa aaa 1b bb bbb 2c cc cccd dd ddd 4e ee eee 5[root@localhost test]# cat test1a aa aaa 1b bb bbb 2c cc ccc 3d dd ddd 4e ee eee 5

解析:当读取第一个文件的A的时候NR 和 FNR 都是从1开始计数,这时NR==FNR 将行全部内容赋值给数组,当读取到第二个文件时,NR!=FNR此时表示已读取到第二个文件,将的内容和$0进行比较如果不相同,则输出行号。

FS

输入字段分割符,默认是以空格为分隔符,在日常中常常文本里面不都以空格分隔,此时就要指定分割符来格式化输入。

[root@localhost test]# cat test4a,b,cd,e,fg,h,ij,k,l[root@localhost test]# awk '{print $1}' test4a,b,cd,e,fg,h,ij,k,l[root@localhost test]# awk 'BEGIN{FS=","}{print $1}' test4adgj

以上,test4里面字母间是以“,” 来分割的,第一种写法,由于,没有指定FS,awk默认是以空格来分割,所以全部内容都当作$1来显示,第二个指定FS以“,”分割,所以能够正常打印。

OFS

输出字段分割符,默认为空格,如果读进来的数据是以空格分割,为了需求可能要求输出是以“-“分割,可以使用OFS进行格式化输出

[root@localhost test]# awk 'BEGIN{FS=" ";OFS="---"}{print $1,$2,$3}' testa---aa---aaab---bb---bbbc---cc---cccd---dd---ddde---ee---eee

RS

输入行分隔符,判断输入部分的行的起始位置,默认是换行符

[root@localhost test]# cat test4a,b,cd,e,fg,h,ij,k,l[root@localhost test]# awk 'BEGIN{RS=","}{print}' test4abcdefghijkl

这里说明一下,RS=“,”将以,为分割当作一行,即a,b a被当作一行,b也被当作一行,但是细心的会发现以“,”分割c和d之间是没有“,“的为什么也当作一行了呢,是因为输入中c后面还有一个换行符\n 即,输入应该是a,b,c\n只不过\n我们看不到,输入中,a一行,b一行,c\nd一行但是输出的时候系统会将\n视为换行符,所以看上去c和d是两行,实际上是一行

ORS

输出行分割符,默认的是换行符,它的机制和OFS机制一样,对输出格式有要求时,可以进行格式化输出

[root@localhost test]# awk 'BEGIN{ORS=","}{print}' test4a,b,c,d,e,f,g,h,i,j,k,l,

全部的分割符,都变成了”,“,具体的格式,可以根据实际需求,进行多种变化。

转载地址:http://dhfef.baihongyu.com/

你可能感兴趣的文章
Redis学习笔记(三)—— 使用redis客户端连接windows和linux下的redis并解决无法连接redis的问题
查看>>
Intellij IDEA使用(一)—— 安装Intellij IDEA(ideaIU-2017.2.3)并完成Intellij IDEA的简单配置
查看>>
Intellij IDEA使用(二)—— 在Intellij IDEA中配置JDK(SDK)
查看>>
Intellij IDEA使用(三)——在Intellij IDEA中配置Tomcat服务器
查看>>
Intellij IDEA使用(四)—— 使用Intellij IDEA创建静态的web(HTML)项目
查看>>
Intellij IDEA使用(五)—— Intellij IDEA在使用中的一些其他常用功能或常用配置收集
查看>>
Intellij IDEA使用(六)—— 使用Intellij IDEA创建Java项目并配置jar包
查看>>
Eclipse使用(十)—— 使用Eclipse创建简单的Maven Java项目
查看>>
Eclipse使用(十一)—— 使用Eclipse创建简单的Maven JavaWeb项目
查看>>
Intellij IDEA使用(十三)—— 在Intellij IDEA中配置Maven
查看>>
面试题 —— 关于main方法的十个面试题
查看>>
集成测试(一)—— 使用PHP页面请求Spring项目的Java接口数据
查看>>
使用Maven构建的简单的单模块SSM项目
查看>>
Intellij IDEA使用(十四)—— 在IDEA中创建包(package)的问题
查看>>
Redis学习笔记(四)—— redis的常用命令和五大数据类型的简单使用
查看>>
Win10+VS2015编译libcurl
查看>>
Windows下使用jsoncpp
查看>>
Ubuntu下测试使用Nginx+uWsgi+Django
查看>>
Windows下编译x264
查看>>
visual studio调试内存泄漏工具
查看>>