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. es6 模板字变量和字符串占位符

    开发者一直在寻找一种创建多行字符串的形式,但要使用单引号双引号字符串一定要在同一行才行. 老办法: 还有其他办法,虽然能实现,但是太啰嗦 es6模板自变量 使用反撇好(`)替换了单双引号 反撇好中的所 ...

  2. Codeforces #451 Div2 F

    #451 Div2 F 题意 给出一个由数字组成的字符串,要求添加一个加号和等号,满足数字无前导 0 且等式成立. 分析 对于这种只有数字的字符串,可以快速计算某一区间的字符串变成数字后并取模的值,首 ...

  3. 阻止a标签的默认事件及延伸

    先贴一段代码 <html lang="en"> <head> <meta charset="UTF-8"> <meta ...

  4. Angular02 通过angular-cli来搭建web前端项目

    利用angular-cli的常见命令: npm i --save 包名   ->  软件依赖    npm i --save-dev 包名     ->  开发依赖    ng new 项 ...

  5. Mybatis之基于XML的增删改查

    这里先吐槽下,写的半天的东西,IE浏览器弹出调试窗口导致写的东西全部没保存,搞得我还要重新用谷歌写,思路全没了,fuck. 前面学习了下spring的DAO层,说起DAO层,那ORM肯定是少不了的,O ...

  6. Codeforces 903D Almost Difference

    Codeforces 903D Almost Difference time limit per test 2 seconds memory limit per test 256 megabytes ...

  7. bzoj 3874: [Ahoi2014]宅男计划

    Description  [故事背景] 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY 不得不依靠叫外卖来维持生计. [问题描述] 外卖店一共有N种食物,分别有1到N编号.第i种 ...

  8. BZOJ 3670: [Noi2014]动物园【KMP变形 】

    3670: [Noi2014]动物园 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2738  Solved: 1475[Submit][Status ...

  9. BZOJ1294: [SCOI2009]围豆豆Bean

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1294 状压dp,dis[s][i][j]表示从(i,j)出发围的状态是s的最短路. 然后判断一 ...

  10. 2017ecjtu-summer training #11 POJ 1018

    Communication System Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 29218   Accepted:  ...