Linux中awk后面的RS, ORS, FS, OFS 含义

一、RS 与 ORS 差在哪
我们经常会说,awk是基于行列操作文本的,但如何定义“行”呢?这就是RS的作用。
  默认情况下,RS的值是\n。下面通过实例来理解下RS。 
echo '1a2a3a4a5' | awk '{print $1}'
1a2a3a4a5
echo '1a2a3a4a5' | awk 'BEGIN{RS="a"}{print $1}'
1
2
3
4
5
我们可以看到,在更改了RS的值后,awk定义的行已经不是我们实际意义中的行了。
  上面RS固定的字符串,RS也可以定义为正则表达式。 
echo '1ab2bc3cd4de5' | awk 'BEGIN{RS="[a-z]+"}{print $1,RS,RT}'
1 [a-z]+ ab
2 [a-z]+ bc
3 [a-z]+ cd
4 [a-z]+ de
5 [a-z]+ 
当我们将RS设置为正则表达式的时候,RT这个变量就有作用了,RS的值始终为我们设定的正则,RT的值则是这个正则实际匹配到的内容。
如果RS被设置为空,那么awk会将连续的空行作为行分隔符,与RS设置成"\n\n+"有什么区别???
  1、忽略文件开头和结尾的空行。且文件不以记录分隔符结束,即最后不是空行,会将最后一个记录的尾\n去掉
  2、不设置RT变量(测试未发现规律,暂时认为RT变量不可用)
  3、影响FS变量
总结下RS的3种情况:
  1) 非空字符串
     以固定字符串作为行分隔符,同时设置变量RT为固定字符串
  2) 正则表达式
     以正则表达式作为行分隔符,同时设置变量RT为正则表达式实际匹配到的字符串
  3) 空字符
     以连续的空行作为行分隔符,如果FS为单个字符,会将\n强制加入到FS变量中
理解了RS,再来理解ORS就简单了。RS是awk读取文件时的行分隔符,ORS则是awk输出时的行结束符。
  更简单的讲,就是awk在输出时,会在每行记录后面增加一个ORS变量所设定的值。
  ORS的值只能设定为字符串,默认情况下,ORS的值是\n 
seq 5 | awk '{print $0}'
1
2
3
4
5
seq 5 | awk 'BEGIN{ORS="a"}{print $0}'
1a2a3a4a5a
我们平常用的 print $0 等价于 printf $0 ORS

二、FS 与 OFS 差在哪
RS是awk用来定义“行”的,那么FS就是awk用来定义“列”的。
  设置变量 FS 与使用 -F 参数是一样的。 
echo '1,2' | awk -F , '{print $1}'
1
echo '1,2' | awk 'BEGIN{FS=","}{print $1}'
1
与 RS 类似,FS 同样可以设置为正则表达式 
echo '1ab2bc3cd4de5' | awk 'BEGIN{FS="[a-z]+"}{print $1,$2,$5}'
1 2 5
FS 有1个特例,就是将FS设置为一个空格,FS=" " ,这也是FS的默认值 
1.In the special case that FS is a single space, fields are separated by runs of spaces and/or tabs and/or newlines.
此时,awk会将连续的 空格 或 制表符(\t) 或 换行符(\n) 作为列的分隔符
  那么,FS=" " 与 FS="[ \t\n]+" 有区别么???
  答案是肯定的 
echo ' 1 2' | awk 'BEGIN{FS=" "}{print $1}'
1
echo ' 1 2' | awk 'BEGIN{FS="[ \t\n]+"}{print $1}'
当FS=" "时,awk会自动去掉行首和行尾的 空格 或 制表符(\t) 或 换行符(\n),但FS="[ \t\n]+"是不会的
  同样,FS也可以设置为空 
echo '123' | awk 'BEGIN{FS=""}{print $1,$2}'
1 2
当FS被设置为空字符串的时候,awk会将一行记录的每个字符做为单独的一列
  类似的,当我们想以固定的长度来分隔列的时候,可以使用 FIELDWIDTHS 来代替 FS
  例如,一行记录的前3个字符作为第一列,接下来的2个字符作为第二列,接下来的4个字符作为第三列 
echo '123456789' | awk 'BEGIN{FIELDWIDTHS="3 2 4"}{print $1,$2,$3}'
123 45 6789
echo '123456789' | awk 'BEGIN{FIELDWIDTHS="3 2 3"}{print $1,$2,$3}'
123 45 678
echo '123456789' | awk 'BEGIN{FIELDWIDTHS="3 2 5"}{print $1,$2,$3}'
123 45 6789
如果定义的长度小于实际的长度,awk会截断,如果大于实际长度,则以实际长度为准。
总结下FS的4种情况:
  1) 非空字符串
     以固定字符串作为列分隔符
  2) 正则表达式
     以正则表达式作为列分隔符
  3) 单个空格
     以连续的 空格 或 制表符(\t) 或 换行符(\n)作为列分隔符
  4) 空字符
     以每个字符做为单独的一列
接下来我们来看看上节提到的问题:
  当 RS="" 时,会将\n强制加入到FS变量中 
cat urfile
1
a
2
a
3
awk -v RS="" '{print "#" $0 "#"}' urfile
#1
a#
#2
a#
#3#
awk -F "b" -v RS="" '{print $1}' urfile
1
2
3
awk -F "c" -v RS="" '{print $1}' urfile
1
2
3
awk -F "c" -v RS="\n\n+" '{print "#" $1 "#"}' urfile
#1
a#
#2
a#
#3
#
如果FS为单个字符,\n始终存在在 FS 中,而 RS="\n\n+" 则不会。
了解的 FS ,我们来看看 OFS ,FS是awk读入记录时的列分隔符,OFS则是awk输出时的列分隔符。
  我们平时使用的 print $1,$2 等价于 print $1 OFS $2 
echo '1 2' | awk -v OFS="|" '{print $1,$2}'
1|2
echo '1 2' | awk -v OFS="|" '{print $1 OFS $2}'
1|2
如果一行记录有很多列,同时想改变输出的分隔符,print $1,$2,$3 ... 启不是很麻烦?
  当然有简单的方法: 
echo '1 2 3 4 5' | awk -v OFS="|" '{print $0}'
1 2 3 4 5
echo '1 2 3 4 5' | awk -v OFS="|" '{$1=$1;print $0}'
1|2|3|4|5
echo '1 2 3 4 5' | awk -v OFS="|" '{NF+=0;print $0}'
1|2|3|4|5
为了使OFS的设置生效,需要改变 $0 ,这里我们是对 awk 撒了个小谎
  $1=$1 或者 NF+=0, $0 本身的内容实际上没有任何改变,只是为了使 OFS 的设置生效
在理解了 RS 和 FS 之后,我们来回顾开始的那句话:“awk是基于行列操作文本的”
  这个说法实际上不是很准确,因为在改变了 RS 后,awk 中的“行”已经不是一般的“行”了
  同样,改变了 FS 后,awk 中的“列”也已经不是一般的“列”了
  因此,准确的应该这样讲:“awk是基于 记录(record) 和 域(field) 操作文本的”

三、0 与 "0" 差在哪
我们先来看一个例子: 
awk 'BEGIN{if(0) print "true";else print "false"}'
false
awk 'BEGIN{if("0") print "true";else print "false"}'
true
为什么同样是 0 ,结果却不一样?
  其实要解释这个问题,只需要弄清楚awk中的“真”与“假”。
  以下3种情况是“假”,其他情况都为“真”
  1) 数字 0
  2) 空字符串
  3) 未定义的值 
 awk 'BEGIN{a=0;if(a) print "true";else print "false"}'
false
awk 'BEGIN{a="";if(a) print "true";else print "false"}'
false
awk 'BEGIN{if(a) print "true";else print "false"}'
false
awk如何去重? 
1.awk '! a[$0] ++'
在解释之前,我们先要了解awk的一个特性:
  awk 会根据语境来给未定义的变量赋初始值 
awk 'BEGIN{print a "" 1}'
1
awk 'BEGIN{print a + 1}'
1
对于未定义的变量,如果要进行字符串操作,会被赋成空字符串 ""
  如果要进行数学运算,会被赋成数字 0
现在我们看看上面的代码 ! a[$0] ++ 等价于 if(! a[$0] ++) print $0
  对于首次出现的记录,a[$0]的值是未定义的,由于后面的 ++ 是数学计算,所以a[$0]会被赋值成数字0
  也是由于 ++ 操作符,会先取值,再计算,所以对于第一行记录实际上是if(! 0) print $0
  ! 是取反,0 是假,! 0 就是真,那么就会执行后面的 print $0
  对于后面出现的重复记录,a[$0] 经过 ++ 的计算已经变为 1、2、3 。。。
  而 ! 1  ! 2  ! 3 ... 都为假,不会打印。
下面我们用黑哥的一段代码来深刻体会一下,用awk打印奇数行: 
seq 10 | awk 'i=!i'
1
3
5
7
9

Linux中awk后面的RS, ORS, FS, OFS 用法相关推荐

  1. Linux中awk后面的RS, ORS, FS, OFS 含义

    awk之RS.ORS与FS.OFS RS:Record Separator,记录分隔符 ORS:Output Record Separate,输出当前记录分隔符 FS:Field Separator, ...

  2. linux awk 区别,linux awk 中 RS,ORS,FS,OFS 区别与联系

    今天在学习时偶尔搜索到了这篇文章,觉得不错,转摘一下:http://blog.51yip.com/shell/1151.html 总结 RS,ORS,FS,OFS的区别和联系. 一,RS与ORS 1, ...

  3. linux awk 中 RS,ORS,FS,OFS 区别与联系

    今天在学习时偶尔搜索到了这篇文章,觉得不错,转摘一下:http://blog.51yip.com/shell/1151.html 总结 RS,ORS,FS,OFS的区别和联系. 一,RS与ORS 1, ...

  4. awk中RS,ORS,FS,OFS区别与联系

    学习awk时,一定要记得动手去实践,只有在实践中才能发现问题,以下就我在学习中和实践中的经验,总结一下RS,ORS,FS,OFS的区别和联系. 一,RS与ORS 1,RS是记录分隔符,默认的分隔符是\ ...

  5. awk内置命令RS,ORS,FS,OFS的使用

    Awk内置命令RS, ORS, FS, OFS FS 指定字段列分隔符 OFS 指定输出字段列分隔符 RS指定行分隔符 默认分隔符为\n ORS指定输出行分隔符 FS指定列分隔符,相当于参数-F.OF ...

  6. linux rs,Linux中的RS, ORS, FS, OFS

    一.RS 与 ORS 差在哪 我们经常会说,awk是基于行列操作文本的,但如何定义"行"呢?这就是RS的作用.  默认情况下,RS的值是\n.下面通过实例来理解下RS. echo ...

  7. linux常用工具awk,linux中awk工具

    awk sed以行为单位处理文件,awk比sed强的地方在于不仅能以行为单位还能以列为单位处理文件.awk缺省的行分隔符是换行,缺省的列分隔符是连续的空格和Tab,但是行分隔符和列分隔符都可以自定义, ...

  8. linux中awk命令_Linux / Unix中的AWK命令

    linux中awk命令 AWK is suitable for pattern search and processing. The script runs to search one or more ...

  9. linux中awk的用法

    awk的用法 首先我们创建一个要测试的文件test 内容: 1 2 3 9 test:test1 str:d strd 第一个 awk 让我们继续,开始使用 awk,以了解其工作原理.在命令行中输入以 ...

最新文章

  1. 华为云微服务引擎CSE大量新特性上线,诚邀您免费体验
  2. 批处理编程的异类——时钟(Clock)
  3. leetcode 1038. 从二叉搜索树到更大和树
  4. jquery 动态添加一行数据,支持动态删除
  5. leetcode103. 二叉树的锯齿形层次遍历(bfs)
  6. 一个适用各类场合的Makefile模板
  7. 【转载】Linux平台软件包管理完全攻略
  8. 浪点服务器芯片,浪点云服务器
  9. POJ3126 Prime Path(BFS)
  10. 2016: 神殿(求二进制1的个数最多的那个数)
  11. buntu12.10 64位 + android-ndk-r9 编译ffmpeg遇到的问题
  12. 九九乘法表php4种,PHP九九乘法表
  13. 云服务器和虚拟主机的区别
  14. Charles 破解版安装图解
  15. 深入理解双线性插值算法
  16. 共享计算机后无法访问磁盘,win7局域网怎么共享整个硬盘,如D盘E盘F盘等等-win7怎么共享磁盘,win7共享后无权限访问...
  17. Python 数值四舍五入碰到遇5不进
  18. HTML+CSS学习笔记(pink老师前端课程笔记--补档)
  19. 周立功先生给学子的话
  20. 计算机学数学物理方法,计算机在数学物理方法习题课中的应用

热门文章

  1. 谦卑的程序员(The Humble Programmer) by E.W.Dijkstra,1972
  2. shader实现飞线效果(three.js练习)
  3. C++ UTF8 互转 Unicode
  4. Android Room 数据库详解
  5. 金融机构数字化转型对央企建筑公司数字化转型的启示
  6. Scala基础(四)
  7. java打包跳过test_maven打包如何跳过测试操作的?
  8. 后面尾缀-T、-X、-TX…分别表示的意思
  9. okhttp3调用接口超时
  10. WEB网站压力测试教程详解