awk有一些内置的变量,本文主要讲述与 行分割符、列分割符、行号、列号有关的变量
FNR表示该记录在其对应文件中的行号, NR表示该记录在整个input stream中的行号。
如果只有一个文件,两者是一样的。如果是多个文件,则每读取一个新的文件时,FNR都会被重置为1,而NR一直增加。
下面两条命令中,第一条用于打印每一行的FNR和内容,第二条用于打印每一行的NR和内容:
FS 表示field分割符,也就是输入中 列的分割符,默认为空格或Tab。 OFS表示输出多个列的时候,列与列之间的分割符,默认为一个空格。
下面的命令打印ipb.txt的第1列和第2列,使用的默认的分割符:
将OFS设为冒号,表示输出中用冒号作分割符,效果如下:
如果将FS设置为".", 则读取输入的时候,读到"."才认为是一列,下面是打印ipb.txt第一列:
qingsong@db2a:~$ cat ipc.txt
hello, world
this is a
sample text of awk
打印每一行有多少列
qingsong@db2a:~$ awk '{print NF}' ipc.txt
2
3
4
打印倒数第2列和最后1列:
qingsong@db2a:~$ awk '{print $(NF-1), $NF}' ipc.txt
hello, world
is a
of awk
RS 表示输入文件中行分割符,默认是一个"\n",
ORS表示输出中,行与行之间的分割符,默认是一个"\n"
以ipc.txt为例子,默认awk使用"\n"作为输出的记录分隔符,可以使用ORS改变这一行为,例如下面的命令使用"#"作为输出行分割符:
qingsong@db2a:~$ awk 'BEGIN { ORS = "#" } {print}' ipc.txt
hello, world#this is a #sample text of awk#qingsong@db2a:~$
比如有下面的文件:
qingsong@db2a:~$ cat ipd.txt
if (a > b);return a;else;return b
直观看起来只有一条记录(一行),但如果把分号当作输入的记录分割符,则有4条记录,下面是打印前3条记录
qingsong@db2a:~$ awk 'BEGIN { RS = ";" } NR <= 3 {print}' ipd.txt
if (a > b)
return a
else
本文用到的测试文件如下:
qingsong@db2a:~$ cat ipa.txt
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
inet addr:192.168.16.128 Bcast:192.168.16.255 Mask:255.255.255.0
inet addr:127.0.0.1 Mask:255.0.0.0
qingsong@db2a:~$ cat ipb.txt
Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
1. FNR 与 NR (行号相关)
说明如下:
FNR current record number in FILENAME.
NR current record number in the total input stream.
FNR表示该记录在其对应文件中的行号, NR表示该记录在整个input stream中的行号。
如果只有一个文件,两者是一样的。如果是多个文件,则每读取一个新的文件时,FNR都会被重置为1,而NR一直增加。
下面两条命令中,第一条用于打印每一行的FNR和内容,第二条用于打印每一行的NR和内容:
qingsong@db2a:~$ awk '{print FNR, $0}' ipa.txt ipb.txt
1 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
2 inet addr:192.168.16.128 Bcast:192.168.16.255 Mask:255.255.255.0
3 inet addr:127.0.0.1 Mask:255.0.0.0
1 Beth 4.00 0
2 Dan 3.75 0
3 Kathy 4.00 10
4 Mark 5.00 20
5 Mary 5.50 22
6 Susie 4.25 18
qingsong@db2a:~$ awk '{print NR, $0}' ipa.txt ipb.txt
1 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
2 inet addr:192.168.16.128 Bcast:192.168.16.255 Mask:255.255.255.0
3 inet addr:127.0.0.1 Mask:255.0.0.0
4 Beth 4.00 0
5 Dan 3.75 0
6 Kathy 4.00 10
7 Mark 5.00 20
8 Mary 5.50 22
9 Susie 4.25 18
2. FS 与 OFS (列分割符)
FS splits records into fields as a regular expression.
OFS inserted between fields on output, initially = " ".
FS 表示field分割符,也就是输入中 列的分割符,默认为空格或Tab。 OFS表示输出多个列的时候,列与列之间的分割符,默认为一个空格。
下面的命令打印ipb.txt的第1列和第2列,使用的默认的分割符:
qingsong@db2a:~$ awk '{print $1,$2}' ipb.txt
Beth 4.00
Dan 3.75
Kathy 4.00
Mark 5.00
Mary 5.50
Susie 4.25
将OFS设为冒号,表示输出中用冒号作分割符,效果如下:
qingsong@db2a:~$ awk 'BEGIN {OFS = ":"} {print $1, $2}' ipb.txt
Beth:4.00
Dan:3.75
Kathy:4.00
Mark:5.00
Mary:5.50
Susie:4.25
如果将FS设置为".", 则读取输入的时候,读到"."才认为是一列,下面是打印ipb.txt第一列:
qingsong@db2a:~$ awk 'BEGIN {FS = "."} {print $1}' ipb.txt
Beth 4
Dan 3
Kathy 4
Mark 5
Mary 5
Susie 4
3. NF (列号相关)
NF number of fields in the current record.
qingsong@db2a:~$ cat ipc.txt
hello, world
this is a
sample text of awk
打印每一行有多少列
qingsong@db2a:~$ awk '{print NF}' ipc.txt
2
3
4
打印倒数第2列和最后1列:
qingsong@db2a:~$ awk '{print $(NF-1), $NF}' ipc.txt
hello, world
is a
of awk
4. ORS与RS (行分割符)
ORS terminates each record on output, initially = "\n".
RS input record separator, initially = "\n".
RS 表示输入文件中行分割符,默认是一个"\n",
ORS表示输出中,行与行之间的分割符,默认是一个"\n"
以ipc.txt为例子,默认awk使用"\n"作为输出的记录分隔符,可以使用ORS改变这一行为,例如下面的命令使用"#"作为输出行分割符:
qingsong@db2a:~$ awk 'BEGIN { ORS = "#" } {print}' ipc.txt
hello, world#this is a #sample text of awk#qingsong@db2a:~$
比如有下面的文件:
qingsong@db2a:~$ cat ipd.txt
if (a > b);return a;else;return b
直观看起来只有一条记录(一行),但如果把分号当作输入的记录分割符,则有4条记录,下面是打印前3条记录
qingsong@db2a:~$ awk 'BEGIN { RS = ";" } NR <= 3 {print}' ipd.txt
if (a > b)
return a
else
qingsong@db2a:~$
关于ORS/RS的应用,我之前写过另一篇文章,如下: