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. Android的Environment.getExternalStorageState的使用

    1.sd状态 sd状态 现象描述  /mnt/sdcard目录是否存在 canRead返回 canWrite返回 MEDIA_MOUNTED  SD卡正常挂载 true true true MEDIA ...

  2. 分享一个JS的Base64加密解密功能

    代码实现: var base64 = (function () { var encodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop ...

  3. Yii2.0源码阅读-从路由到控制器

    之前的文章弄清了一次请求的开始到结束.主要讲了Yii Applicaton实例的创建.初始化,UrlManager如何返回Yii中的路由信息,到runAction,最后将Response发送给客户端. ...

  4. Django查询笔记1

    models.Book.objects.filter(**kwargs): querySet [obj1,obj2] models.Book.objects.filter(**kwargs).valu ...

  5. Eclipse导入Hadoop源码项目及编写Hadoop程序

    一 Eclipse导入Hadoop源码项目 基本步骤: 1)在Eclipse新建一个java项目[hadoop-1.2.1] 2)将Hadoop压缩包解压目录src下的core,hdfs,mapred ...

  6. Educational Codeforces Round 21(A.暴力,B.前缀和,C.贪心)

    A. Lucky Year time limit per test:1 second memory limit per test:256 megabytes input:standard input ...

  7. Win10没有以太网图标如何找回?以太网适配器不见了怎么恢复?

    Win10以太网适配器不见了怎么恢复?以太网其实就是Win7系统中常说的"本地连接"假若用户发现网络适配器中的以太网适配器图标不见了,可以在设备管理器中添加一些这类适配器,具体过程 ...

  8. 创建jedis对象

    1.先在taotao-parent的pom.xml中复制 以下内容到rest的pom.xml中 <!-- Redis客户端 --> <dependency> <group ...

  9. Centos7网络配置-转载

    一. 查看网络地址: centos7取消了ifconfig命令,使用ip addr命令查看IP地址 二.配置网络 用VirtualBox安装的CentOS7,安装完成后,发现无法上网,于是到网上查了一 ...

  10. Java的语言特点详解

    1)简单性:java从C++简化而来,设计者们把C++语言中许多可用的特征去掉了,这些特征是一般程序员很少使用的.java还剔除了C++操作符过载和指针操作. 2)面向对象:java是一个面向对象的语 ...