awk学习手记-2
文本中的分隔符用处有两处:
1、分割字段;
2、分割行;
字段和行的分割都主要涉及两种操作“输入分隔符”和“输出分隔符”。
我们会通过实例讲解其中技巧。
输入字段分隔符:field separator , FS
默认是空格,以空格作为分隔符对每一行进行分割,FS指定了每行如何分割画段;
输出字段分隔符:output field separator , OFS
输出到屏幕上时,默认以空格作为输出分隔符,OFS指定了文本以什么形式输出;
输入记录分隔符:record separator , RS
默认是回车换行,\n,可以指定输入时的换行符
输出记录分隔符:output record separator , ORS
一、输入分隔符
当awk逐行处理文本时,以输入分隔符为标准,将文本切割成多个片段,可以认为指定分隔符。
****例 1、awk默认使用空格分割文本
[root@my127 awk]# awk '{print}' 5.txt
qaz wsx#edc rfv
123 456#789 098
tgb yhn#ujm iko
awk将每行分割成三段,实际上我们在屏幕上看到的都是输出的内容,输入分割早已完成,只是按照约定俗成的规矩输出。
当我们指定了输入分隔符,就可以感受到变化:
例 2、
指定以#作为输入分隔符
[root@my127 awk]# awk -v FS=’#’ ‘{print $1,$2}’ 5.txt
qaz wsx edc rfv
123 456 789 098
tgb yhn ujm iko
该例子中我们通过 -v FS=’#'设置内部变量指定了#作为输入分隔符,awk将每一行都通过#为我们分割文本。
也可以使用-F选项指定
[root@my127 awk]# awk -F# '{print $1,$2}' 5.txt
qaz wsx edc rfv
123 456 789 098
tgb yhn ujm iko
tips:指定变量的时候最好使用引号。
注意:
1、这里使用FS指定了分隔符,是以分隔符为界将文本划分成若干部分,print语句中必须指定要输出哪些列!
1,1,1, 2或者$n,,不能使用print/print $0!
[root@my127 awk]# awk -v FS='#' '{print $0}' 5.txt
qaz wsx#edc rfv
123 456#789 098
tgb yhn#ujm iko
二、输出分隔符
当awk为我们输出每一列时,会默认使用空格隔开每一列数据,
[root@my127 awk]# cat 6.txt
qwe#rty#yui#iop
asd#fgh#jkl#zxc
mnb#plm#ijn#awr

上图中红线标注的空格部分就是awk默认的输出分隔符,我们可以通过OFS来指定输出分隔符,用法和FS一样
[root@my127 awk]# cat 5.txt
qaz wsx#edc rfv
123 456#789 098
tgb yhn#ujm iko
[root@my127 awk]# awk -v OFS='***' '{print $1,$2,$3}' 5.txt
qaz***wsx#edc***rfv
123***456#789***098
tgb***yhn#ujm***iko
以上实例说明:首先awk按照空格来分割文本,然后以***作为输出分隔符,输出文本
三、输入输出分隔符一同使用
[root@my127 awk]# awk -v FS='#' -v OFS='***' '{print $1,$2}' 5.txt
qaz wsx***edc rfv
123 456***789 098
tgb yhn***ujm iko
**FS指定#作为输入分隔符,将每行分为两段,OFS指定输出分隔符以固定形式输出文本。
我们知道输入分隔后是两个字段,当你指定输出逻辑上不存在的字段时,awk以为你指定的就是空白字段,仍然会以输出分隔符格式化文本。
[root@my127 awk]# awk -v FS=’#’ -v OFS=’***’ ‘{print $1,$2,$3,$4}’ 5.txt
qaz wsx***edc rfv ******
123 456***789 098******
tgb yhn***ujm iko******
四、输入行分隔符RS
默认行分隔符就是我们所理解的回车换行,现在我们想以空格作为换行符,即遇到空格就换行
[root@my127 awk]# awk '{print NR,$0}' 5.txt
1 qaz wsx#edc rfv
2 123 456#789 098
3 tgb yhn#ujm iko
[root@my127 awk]# awk -v RS=' ' '{print NR,$0}' 5.txt
1 qaz
2 wsx#edc
3 rfv
123
4 456#789
5 098
tgb
6 yhn#ujm
7 iko

如以上例子所示,首先以默认行分隔符分割文本,这时文本共有3行;
然后指定空格作为行分割符,遇到空格就换行,显示文本一共有7行;
图中第三行那里是因为换车换行是人类的固定思维,awk认定空格才是换行的标致,所以回车前后只能算是一行。
注:RS只是执行了输入分割,分割完成后还是按照约定俗成,在屏幕上按照换行来显示文本
五、输出行分隔符
当我们指定了输出行分隔符后,就不再是人类约定俗成的那一套,比如我们指定‘&&&’作为输出行分隔符
[root@my127 awk]# cat 4.txt
root test prom tmp
123 456 78900 00
WWW GOO GLE COM
[root@my127 awk]# awk -v ORS='&&&' '{print NR,$0}' 4.txt
1 root test prom tmp &&&2 123 456 78900 00&&&3 WWW GOO GLE COM&&&
输出时不再以回车换行而是&&&来连接各行。
解释:在没有指定输出行分隔符之前,awk跟人类的逻辑思维一致,每逢一行结束就会“另起一行”,即回车换行。
但是当认为指定了输出行分隔符后,每逢一行结束,awk还是会“另起一行”,不过这个时候awk认为的另起一行就是输出“&&&”,
就会以指定字符&&&来作为标准连接两行。
六、输入输出行分隔符混用
[root@my127 awk]# cat 4.txt
root test prom tmp
123 456 78900 00
WWW GOO GLE COM
[root@my127 awk]# awk -v RS=' ' '{print NR,$0}' 4.txt
1 root
2 test
3 prom
4 tmp
123
5
6 456
7
8 78900
9
10 00
WWW
11
12 GOO
13
14 GLE
15
16 COM
[root@my127 awk]# awk -v RS=' ' -v ORS='&&&' '{print NR,$0}' 4.txt
1 root&&&2 test&&&3 prom&&&4 tmp
123&&&5 &&&6 456&&&7 &&&8 78900&&&9 &&&10 00
WWW&&&11 &&&12 GOO&&&13 &&&14 GLE&&&15 &&&16 COM
能看得懂以上例子为什么会这样输出文本,就说明我们对输入,输出分隔符明白了。
疑问:
以下例子中,指定输入字段分割符为‘#’,输出字段分隔符为‘&&&’时,正常分割字段
但是不指定任何输入分隔符,只指定输出分割符时,每行末尾被加上‘&&&’?
[root@my127 sevenday]# cat hao.txt
host#lafu#ask
asdasd#asdjk#asd
as#gv#detfb
[root@my127 sevenday]# awk -v FS='#' -v OFS='&&&' '{print $1,$2,$3}' hao.txt
host&&&lafu&&&ask
asdasd&&&asdjk&&&asd
as&&&gv&&&detfb
[root@my127 sevenday]# awk -v OFS='&&&' '{print $1,$2,$3}' hao.txt
host#lafu#ask&&&&&&
asdasd#asdjk#asd&&&&&&
as#gv#detfb&&&&&&
答:因为默认的分隔符是空格,那么目标文件中被视为只有一列。
awk -v OFS='&&&' '{print ***$1,$2,$3***}' hao.txt
而语句中指明了要打印第一列,第二列,第三列,
那么awk会使用你指定的输出分隔符去填充本不存在的列!

深入解析AWK中输入输出字段与记录分隔符的使用技巧,包括FS、OFS、RS、ORS的详细说明及示例,帮助读者掌握AWK文本处理核心概念。

2393

被折叠的 条评论
为什么被折叠?



