详细分析awk如何读取文件
awk读取输入文件时,每次读取一条记录(record)(默认情况下按行读取,所以此时记录就是行)。每读取一条记录,将其保存到$0中,然后执行一次main代码段。
[root@docker-01 ~]# awk '{print $0}' a.txt
如果是空文件,则因为无法读取到任何一条记录,将导致直接关闭文件,而不会进入main代码段。
[root@docker-01 ~]# touch x.log
[root@docker-01 ~]# awk '{print $0}' x.log
可设置表示输入记录分隔符的预定义变量RS(Record Separator)来改变每次读取的记录模式。
# RS="\n" 、 RS="m"
[root@docker-01 ~]# awk 'BEGIN{RS="\n"}{print $0}' a.txt
ID name gender age email phone
1 Bob male 28 abc@qq.com 18023394012
2 Alice female 24 def@gmail.com 18084925203
3 Tony male 21 aaa@163.com 17048792503
4 Kevin male 21 bbb@189.com 17023929033
5 Alex male 18 ccc@xyz.com 18185904230
6 Andy female 22 ddd@139.com 18923902352
7 Jerry female 25 exdsa@189.com 18785234906
8 Peter male 20 bax@qq.com 17729348758
9 Steven female 23 bc@sohu.com 15947893212
10 Bruce female 27 bcbd@139.com 13942943905
[root@docker-01 ~]# awk 'BEGIN{RS="m"}{print $0}' a.txt
ID na
e gender age e
ail phone
1 Bob
ale 28 abc@qq.co
18023394012
2 Alice fe
ale 24 def@g
ail.co
18084925203
3 Tony
ale 21 aaa@163.co
17048792503
4 Kevin
ale 21 bbb@189.co
17023929033
5 Alex
ale 18 ccc@xyz.co
18185904230
6 Andy fe
ale 22 ddd@139.co
18923902352
7 Jerry fe
ale 25 exdsa@189.co
18785234906
8 Peter
ale 20 bax@qq.co
17729348758
9 Steven fe
ale 23 bc@sohu.co
15947893212
10 Bruce fe
ale 27 bcbd@139.co
RS通常设置在BEGIN代码块中,因为要先于读取文件就确定好RS分隔符。
RS指定输入记录分隔符时,所读取的记录中是不包含分隔符字符的。例如RS="a",则$0中一定不可能出现字符a。
RS可能两种情况
RS为单个字符:直接使用该字符来分割记录 RS为多个字符:将其当作正则表达式,只要匹配正则表达式的符号,都用来分割记录 设置预定义变量IGNORECASE为非零值,正则匹配时表过忽略大小写, 兼容模式下,只有首字符才生效,下面使用正则模式去分割记录。
特殊的RS值用来解决特殊读取需求:
RS="":按段落读取 RS="\0":一次性读取所有数据,但有些特殊文件中包含了空字符\0 RS="^$":真正的一次性读取所有数据,因为非空文件不可能匹配成功 RS="\n+":按行读取,但忽略所有空行
示例:
# 按段落读取:RS=''
[root@docker-01 ~]# awk 'BEGIN{RS=""} {print $0"------"}' a.txt
ID name gender age email phone
1 Bob male 28 abc@qq.com 18023394012
2 Alice female 24 def@gmail.com 18084925203
3 Tony male 21 aaa@163.com 17048792503
4 Kevin male 21 bbb@189.com 17023929033
5 Alex male 18 ccc@xyz.com 18185904230
6 Andy female 22 ddd@139.com 18923902352
7 Jerry female 25 exdsa@189.com 18785234906
8 Peter male 20 bax@qq.com 17729348758
9 Steven female 23 bc@sohu.com 15947893212
10 Bruce female 27 bcbd@139.com 13942943905------
# 一次性读取所有数据:RS='\0' RS="^$"
[root@docker-01 ~]# awk 'BEGIN{RS='\0'}{print $0"------"}' a.txt
ID name gender age email phone
1 Bob male 28 abc@qq.com 18------
23394------
12
2 Alice female 24 def@gmail.com 18------
849252------
3
3 Tony male 21 aaa@163.com 17------
487925------
3
4 Kevin male 21 bbb@189.com 17------
23929------
33
5 Alex male 18 ccc@xyz.com 181859------
423------
6 Andy female 22 ddd@139.com 189239------
2352
7 Jerry female 25 exdsa@189.com 187852349------
6
8 Peter male 2------
bax@qq.com 17729348758
9 Steven female 23 bc@sohu.com 15947893212
1------
Bruce female 27 bcbd@139.com 139429439------
5
------
[root@docker-01 ~]# awk 'BEGIN{RS="^$"}{print $0"------"}' a.txt
ID name gender age email phone
1 Bob male 28 abc@qq.com 18023394012
2 Alice female 24 def@gmail.com 18084925203
3 Tony male 21 aaa@163.com 17048792503
4 Kevin male 21 bbb@189.com 17023929033
5 Alex male 18 ccc@xyz.com 18185904230
6 Andy female 22 ddd@139.com 18923902352
7 Jerry female 25 exdsa@189.com 18785234906
8 Peter male 20 bax@qq.com 17729348758
9 Steven female 23 bc@sohu.com 15947893212
10 Bruce female 27 bcbd@139.com 13942943905
------
# 忽略空行:RS='\n+'
[root@docker-01 ~]# awk 'BEGIN{RS="\n+"}{print $0"------"}' a.txt
ID name gender age email phone------
1 Bob male 28 abc@qq.com 18023394012------
2 Alice female 24 def@gmail.com 18084925203------
3 Tony male 21 aaa@163.com 17048792503------
4 Kevin male 21 bbb@189.com 17023929033------
5 Alex male 18 ccc@xyz.com 18185904230------
6 Andy female 22 ddd@139.com 18923902352------
7 Jerry female 25 exdsa@189.com 18785234906------
8 Peter male 20 bax@qq.com 17729348758------
9 Steven female 23 bc@sohu.com 15947893212------
10 Bruce female 27 bcbd@139.com 13942943905------
# 忽略大小写:预定义变量IGNORECASE设置为非0值
[root@docker-01 ~]# awk 'BEGIN{IGNORECASE=1}{print $0"------"}' RS='[ab]' a.txt
ID n------
me gender ------
ge em------
il phone
1 ------
o------
m------
le 28 ------
------
c@qq.com 18023394012
2 ------
lice fem------
le 24 def@gm------
il.com 18084925203
3 Tony m------
le 21 ------
------
------
@163.com 17048792503
4 Kevin m------
le 21 ------
------
------
@189.com 17023929033
5 ------
lex m------
le 18 ccc@xyz.com 18185904230
6 ------
ndy fem------
le 22 ddd@139.com 18923902352
7 Jerry fem------
le 25 exds------
@189.com 18785234906
8 Peter m------
le 20 ------
------
x@qq.com 17729348758
9 Steven fem------
le 23 ------
c@sohu.com 15947893212
10 ------
ruce fem------
le 27 ------
c------
d@139.com 13942943905
------
预定义变量RT:
在awk每次读完一条记录时,会设置一个称为RT的预定义变量,表示Record Termination。
当RS为单个字符时,RT的值和RS的值是相同的。
当RS为多个字符(正则表达式)时,则RT设置为正则匹配到记录分隔符之后,真正用于划分记录时的字符。
当无法匹配到记录分隔符时,RT设置为控制空字符串(即默认的初始值)。
awk 'BEGIN{RS="(fe)?male"}{print RT}' a.txt
[root@docker-01 ~]# awk 'BEGIN{RS="(fe)?male"}{print RT}' a.txt
male
female
male
male
male
female
female
male
female
female
两种行号:NR和FNR
在读取每条记录之后,将其赋值给$0,同时还会设置NR、FNR、RT。
- NR:所有文件的行号计数器
- FNR:是各个文件的行号计数器
[root@docker-01 ~]# awk '{print NR}' a.txt a.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@docker-01 ~]# awk '{print FNR}' a.txt a.txt
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
[root@docker-01 ~]#
来源:https://www.cnblogs.com/liujunjun/p/12389182.html