改变awk默认的分隔符
上面说到awk默认是用空格来进行列分隔的,如果想换成冒号或别的字符该如何处理呢?
- awk 'BEGIN {OFS=":"}{print NR,$0}' arr.dat
输出结果:
- 1:1034 7:26
- 2:1025 7:27
- 3:1101 7:32
- 4:1006 7:45
- 5:1012 7:46
- 6:1028 7:49
- 7:1051 7:51
- 8:1029 7:57
- 9:1042 7:59
- 10:1008 8:01
- 11:1052 8:05
- 12:1005 8:12
- 13:1005 8:13
- 14:1005 8:13
- 15:1005 8:13
可见,行号与行记录之间的分隔符已经换成了冒号,但行记录中的空白不变,如果要改变行记录中每一列的分隔符,试试下面的程序:
- awk 'BEGIN {OFS=":"}{print NR,$1,$2}' arr.dat
输出结果:
- 1:1034:7:26
- 2:1025:7:27
- 3:1101:7:32
- 4:1006:7:45
- 5:1012:7:46
- 6:1028:7:49
- 7:1051:7:51
- 8:1029:7:57
- 9:1042:7:59
- 10:1008:8:01
- 11:1052:8:05
- 12:1005:8:12
- 13:1005:8:13
- 14:1005:8:13
- 15:1005:8:13
需要对上面的程序有更多的解释,因为有几个新的东东出现了。
第一个是BEGIN,与之相对的还有END。前者通常用来改变内建变量的值,它会在输入文件被处理之前执行。后者则会在所有的处理完成之后执行,上面取文件总行数的例子中我们已经用到了这个技巧。
另外,在awk中,文件是可选的,比如写一个hello world:
- awk 'BEGIN {print "Hello, world!"}'
因为BEGIN是在文件处理之前,所以就算没有文件,它也会执行
第二个东东是OFS,这个就是awk的默认分隔符,这样的内建变量还有很多,见下表:
变量 | 描述 |
---|---|
$n | 当前记录的第n个字段,字段间由FS分隔。 |
$0 | 完整的输入记录。 |
ARGC | 命令行参数的数目。 |
ARGIND | 命令行中当前文件的位置(从0开始算)。 |
ARGV | 包含命令行参数的数组。 |
CONVFMT | 数字转换格式(默认值为%.6g) |
ENVIRON | 环境变量关联数组。 |
ERRNO | 最后一个系统错误的描述。 |
FIELDWIDTHS | 字段宽度列表(用空格键分隔)。 |
FILENAME | 当前文件名。 |
FNR | 同NR,但相对于当前文件。 |
FS | 字段分隔符(默认是任何空格)。 |
IGNORECASE | 如果为真,则进行忽略大小写的匹配。 |
NF | 当前记录中的字段数。 |
NR | 当前记录数。 |
OFMT | 数字的输出格式(默认值是%.6g)。 |
OFS | 输出字段分隔符(默认值是一个空格)。 |
ORS | 输出记录分隔符(默认值是一个换行符)。 |
RLENGTH | 由match函数所匹配的字符串的长度。 |
RS | 记录分隔符(默认是一个换行符)。 |
RSTART | 由match函数所匹配的字符串的第一个位置。 |
SUBSEP | 数组下标分隔符(默认值是\034)。 |
对于上面的程序的解释就很好理解了:在处理文件之前,将列分隔符换成冒号,然后逐行输出,并追加行号。
本文转自 ustb80 51CTO博客,原文链接:http://blog.51cto.com/ustb80/1033618,如需转载请自行联系原作者