CU社区shell板块awk十三问整理

一、RS=""

当 RS="" 时,会将\n强制加入到FS变量中,因为RS为空时,是将连续多空行作为分隔符,近似于\n\n+,\n就不能作为行分隔符,所以此时awk默认将\n归为FS

[root@localhost ~]# cat urfile
1
a 2
a 3
[root@localhost ~]# awk -v RS="" '{print "#" $0 "#"}' urfile
#1
a#
#2
a#
#3#

若文件展示位一行,即在硬盘中存贮方式

1\na\n\n2\na\n\n3\n

将内容转化为熟悉的理解方式,RS=\n

1\na
2\na
3
  • 执行后的结果应该为
#1\na#
#2\na#
#3#
  • 实际结果展示
[root@localhost ~]# awk -v RS="" '{print "#" $0 "#"}' urfile
#1
a#
#2
a#
#3#
[root@localhost ~]# awk -v RS="" '{print "#" $1 "#"}' urfile
#1#
#2#
#3#
  • 如果RS被设置为空,那么awk会将连续的空行作为行分隔符,与RS设置成"\n\n+"有什么区别???
  1. 忽略文件开头和结尾的空行。且文件不以记录分隔符结束,即最后不是空行,会将最后一个记录的尾\n去掉
  2. 设置RT变量未空
  3. FS变量
总结下RS的3种情况:
  1. 非空字符串

    以固定字符串作为行分隔符,同时设置变量RT为固定字符串
  2. 正则表达式

    以正则表达式作为行分隔符,同时设置变量RT为正则表达式实际匹配到的字符串
  3. 空字符

    以连续的空行作为行分隔符,如果FS为单个字符,会将\n强制加入到FS变量中
理解了RS,再来理解ORS就简单了。RS是awk读取文件时的行分隔符,ORS则是awk输出时的行结束符。
更简单的讲,就是awk在输出时,会在每行记录后面增加一个ORS变量所设定的值。
ORS的值只能设定为字符串,默认情况下,ORS的值是\n
[root@localhost ~]# seq 5 | awk '{print $0}'
1
2
3
4
5
[root@localhost ~]# seq 5 | awk 'BEGIN{ORS="a"}{print $0}'
1a2a3a4a5a
我们平常用的 print $0 等价于 printf $0 ORS

二、FS=""

  • 当FS被设置为空字符串的时候,awk会将一行记录的每个字符做为单独的一列

  • 类似的,当我们想以固定的长度来分隔列的时候,可以使用 FIELDWIDTHS 来代替 FS

  • 例如,一行记录的前3个字符作为第一列,接下来的2个字符作为第二列,接下来的4个字符作为第三列

[root@localhost ~]# echo '123456789' | awk 'BEGIN{FIELDWIDTHS="3 2 4"}{print $1,$2,$3}'
123 45 6789
[root@localhost ~]# echo '123456789' | awk 'BEGIN{FIELDWIDTHS="3 2 3"}{print $1,$2,$3}'
123 45 678
[root@localhost ~]# echo '123456789' | awk 'BEGIN{FIELDWIDTHS="3 2 5"}{print $1,$2,$3}'
123 45 6789
总结下FS的4种情况:
  1. 非空字符串

    以固定字符串作为列分隔符
  2. 正则表达式

    以正则表达式作为列分隔符
  3. 单个空格

    以连续的 空格 或 制表符(\t) 或 换行符(\n)作为列分隔符
  4. 空字符

    以每个字符做为单独的一列

三、OFS

为了使OFS的设置生效,需要改变 $0 ,这里我们是对 awk 撒了个小谎

$1=$1 或者 NF+=0, $0 本身的内容实际上没有任何改变,只是为了使 OFS 的设置生效

这里执行$1=$1;只是为了欺骗awk,让awk认为对文本进行了修改,否则awk将输入结果直接输出不做修改

四、真假

其实要解释这个问题,只需要弄清楚awk中的“真”与“假”。

以下3种情况是“假”,其他情况都为“真”

  1. 数字 0
  2. 空字符串
  3. 未定义的值
  • awk 会根据语境来给未定义的变量赋初始值
[root@localhost ~]# awk 'BEGIN{print a "" 1}'
1
[root@localhost ~]# 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打印奇数行:

[root@localhost ~]# seq 10 | awk 'i=!i'
1
3
5
7
9

awk中的赋值功能是先处理"="右边的内容(假设需要处理的话);

  • i变量没有赋值,为假。

    • 第一次执行!i则为真,将结果赋值给i;
    • 第二次执行!i则为假,将结果赋值给i;
    • 依次类推;真假循环
插一句  awk打印偶数行
awk 'i++%2'

五、一些awk内置变量

  1. 上面还有出现了一个变量FILENAME,这个变量的值就是awk当前处理的文件的文件名
  2. 这里我们还有几个变量需要了解:ARGV、ARGC、ARGIND
  3. ARGV 是一个数组,它记录着命令行的所有参数的值
  4. ARGC 是命令行参数的个数,(不包括-F、-v之类的awk参数)
  5. ARGIND 是ARGV数组的索引值,从0到ARGC-1

当我们想去了解这些变量时,最简单并且最有效的方法就是print

[root@localhost ~]# awk 'BEGIN{for(i=0;i<ARGC;i++) print "ARGV["i"]="ARGV[i]}{print ARGV[ARGIND],ARGIND,ARGC,$0}' [abc].txt
ARGV[0]=awk
ARGV[1]=a.txt
ARGV[2]=b.txt
ARGV[3]=c.txt
a.txt 1 4 a
a.txt 1 4 b
a.txt 1 4 c
b.txt 2 4 d
b.txt 2 4 e
b.txt 2 4 f
c.txt 3 4 g
c.txt 3 4 h
c.txt 3 4 i
在任何情况下,ARGV[ARGIND]始终是有值的,而FILENAME则不一定

六、awk的IO

awk中的IO就不得不提 getline,其实还有就是next跟nextfile

  • 这里主要说下getline

  • getline的用法很灵活,可以从awk当前处理的文件中获取下一行记录

  • 也可以从外部的文件或者管道中获取记录,每次只取一行,赋给$0或者变量var

  • 先来看个简单的例子,实现 grep -A1

[root@localhost ~]# seq 10 | grep -A1 5
5
6
[root@localhost ~]# seq 10 | awk '/5/{print;getline;print}'
5
6
  • 将两个输出或者说变量上每列分别合在一起的方法
[root@localhost ~]# var1='a
> b
> c
> d'
[root@localhost ~]# var2='A
> B
> C
> D'
[root@localhost ~]# export var2
[root@localhost ~]# echo "$var1" | awk '{"echo \042$var2\042"|getline var2;print $1""var2}'
aA
bB
cC
dD

CU社区shell板块awk十三问整理的更多相关文章

  1. Shell脚本使用汇总整理

    Shell脚本使用汇总整理 一.Shell脚本常用的头部格式: 头部的作用就是告知linux此脚本的类型: 常用的头部格式如下:(/bin/bash,是bash的路径,如果不知道路径可以通过which ...

  2. Shell脚本使用汇总整理——达梦数据库备份脚本

    Shell脚本使用汇总整理——达梦数据库备份脚本 Shell脚本使用的基本知识点汇总详情见连接: https://www.cnblogs.com/lsy-blogs/p/9223477.html 脚本 ...

  3. Shell脚本使用汇总整理——mysql数据库5.7.8以前备份脚本

    Shell脚本使用汇总整理——mysql数据库5.7.8以前备份脚本 Shell脚本使用的基本知识点汇总详情见连接: https://www.cnblogs.com/lsy-blogs/p/92234 ...

  4. Shell脚本使用汇总整理——mysql数据库5.7.8以后备份脚本

    Shell脚本使用汇总整理——mysql数据库5.7.8以后备份脚本 Shell脚本使用的基本知识点汇总详情见连接: https://www.cnblogs.com/lsy-blogs/p/92234 ...

  5. Shell脚本使用汇总整理——文件夹及子文件备份脚本

    Shell脚本使用汇总整理——文件夹及子文件备份脚本 Shell脚本使用的基本知识点汇总详情见连接: https://www.cnblogs.com/lsy-blogs/p/9223477.html ...

  6. AWK增强的文本处理shell特征--AWK完全手册

    AWK这是一个很好的文字处理工具. 它不仅 Linux 中也是不论什么环境中现有的功能最强大的数据处理引擎之中的一个. 本文主要摘录池中龙写的Unixawk使用手冊(第二版),对当中内容略微修改.感谢 ...

  7. Shell 学习—AWK介绍

    Shell 学习—AWK = = = 安装awk root@kiki-desktop:~/shell# apt-get install gawk gawk-doc = = = awk 是一种程序语言. ...

  8. Shell之awk

    Shell之awk 目录 Shell之awk 一.awk概述 1. awk的工作原理 2. 命令格式 3. awk常见的内建变量(可直接用) 二.操作实例 1. 按行输出文本 2. 按字段输出文本 3 ...

  9. shell常用命令归类整理

    shell 命令整理     bash shell 含有许多功能,因此有许多可用的命令:本文档仅罗列了一些常用命令及其使用频率较高的参数.#本文档仅罗列了一些常用命令及其使用频率较高的参数.#vers ...

随机推荐

  1. Redis的key过期处理策略

    Redis中有三种处理策略:定时删除.惰性删除和定期删除. 定时删除:在设置键的过期时间的时候创建一个定时器,当过期时间到的时候立马执行删除操作.不过这种处理方式是即时的,不管这个时间内有多少过期键, ...

  2. Python 解析构建数据大杂烩 -- csv、xml、json、excel

    Python 可以通过各种库去解析我们常见的数据.其中 csv 文件以纯文本形式存储表格数据,以某字符作为分隔值,通常为逗号:xml 可拓展标记语言,很像超文本标记语言 Html ,但主要对文档和数据 ...

  3. 【C#系列】浅谈委托和委托

    本篇文章更适合具有一定开发经验,一定功底,且对底层代码有所研究的朋友!!! 本篇文章主要采用理论和代码实例相结合方法来论述委托和事件,涉及到一些边界技术,如软件架构的OCP原则(开-闭原则), 软件架 ...

  4. Django---->模板层(template)

    模板层(template) 你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. 1 2 3 4 def current_datetime ...

  5. Mysql ibd文件恢复指南

    背景 mysql在使用的过程中,难免遇到数据库表误操作,基于此,作者亲力亲为,对mysql数据表ibd文件的恢复做以下详细的说明,对开发或者初级dba提供一定的指导作用,博客中如若存在相关问题,请指明 ...

  6. JavaScript获取页面宽度高度

    网页可见区域宽:document.body.clientWidth网页可见区域高:document.body.clientHeight网页可见区域宽:document.body.offsetWidth ...

  7. Hadoop(十五)MapReduce程序实例

    一.统计好友对数(去重) 1.1.数据准备 joe, jon joe , kia joe, bob joe ,ali kia, joe kia ,jim kia, dee dee ,kia dee, ...

  8. [Codeforces 696D] Legen...

    题目大意: 给出一些匹配串,要造一个长度不超过L的字符串,每个匹配串有自己的价值,匹配串每次出现在字符串里都会贡献一次价值...要求可能得到的最大价值. 匹配串总长不超200,L<=10^14, ...

  9. win10系统下如何用命令行的方式打开画图软件

    按 win + r 后输入命令 mspaint  再 回车 即可!如下图所示:

  10. Qt 共享库(动态链接库)和静态链接库的创建及调用

    前言: 编译器 Qt Creator, 系统环境 win7 64 位 1.创建共享库: 新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sh ...