Awk 有几个非常强力的内置变量.通常来说 分为两种类型的内置变量: - 第一种是定义的变量可以改变, 比如字段分隔(FS)与记录分隔(RS) - 第二种是可以用来数据处理或者数据总结 比如记录数(NR)与字段数目(NF) 文中 介绍了: FS,OFS, RS, ORS, NR, NR, FNR

FS: 输入字段分隔符变量

FS(Field Separator) 读取并解析输入文件中的每一行时 默认按照空格分隔为字段变量,$1,$2...等。FS 变量被用来设置每一记录的字段分隔符号。FS 可以是任意的字符串或者正则表达式.你可以使用下面两种方式来声名FS:

使用 -F 命令选项

作为设置为普通变量使用

语法:$ awk -F 'FS' 'commands' inputfilename或者$ awk 'BEGIN{FS="FS";}'

FS 可以是任意字符或者正则表达式

FS 可以多次改变, 不过会保持不变直到被明确修改。不过如果想要改变字段分隔符, 最好是在读入文本之前就改变 FS, 这样改变才会在你读入的文本生效。

下面是一个使用 FS 读取 /etc/passwd 以 : 作为分隔符的例子

$ cat etc_passwd.awkBEGIN{FS=":";print "NametUserIDtGroupIDtHomeDirectory";}{    print $1"t"$3"t"$4"t"$6;}END {    print NR,"Records Processed";}

使用结果:

$ awk -f etc_passwd.awk /etc/passwdName  UserID GroupID    HomeDirectorygnats    41    41    /var/lib/gnatslibuuid    100    101    /var/lib/libuuidsyslog    101    102    /home/sysloghplip    103    7    /var/run/hplipavahi    105    111    /var/run/avahi-daemonsaned    110    116    /home/sanedpulse    111    117    /var/run/pulsegdm    112    119    /var/lib/gdm8 Records Processed

OFS: 输出字段分隔符变量

OFS(Output Field Separator) 相当与输出上的 FS, 默认是以一个空格字符作为输出分隔符的 下面是一个 OFS 的例子:

$ awk -F':' '{print $3,$4;}' /etc/passwd41 41100 101101 102103 7105 111110 116111 117112 119

注意命令中的 print 语句的, 表示的使用一个空格连接两个参数 也就是默认的OFS的值。因此 OFS 可以像下面那样插入到输出的字段之间:

$ awk -F':' 'BEGIN{OFS="=";} {print $3,$4;}' /etc/passwd41=41100=101101=102103=7105=111110=116111=117112=11

RS: 记录分隔符

RS(Record Separator)定义了一行记录。读取文件时 默认将一行作为一条记录。 下面的例子以 student.txt 作为输入文件 记录之间用两行空行分隔 并且每条记录的每个字段用一个换行符分隔:

$ cat student.txtJones2143788477Gondrol2321565845RinRao2122383765Edwin2537786745Dayan2415304720

然后下面的脚本就会从student.txt输出两项内容:

$ cat student.awkBEGIN {    RS="nn";    FS="n";}{    print $1,$2;}$ awk -f student.awk student.txtJones 2143Gondrol 2321RinRao 2122Edwin 2537Dayan 2415

在 student.awk 中 把每个学生的详细信息作为一条记录  这是因为RS(记录分隔符)是被设置为两个换行符。并且因为 FS (字段分隔符)是一个换行符 所以一行就是一个字段。

ORS: 输出记录分隔符变量

ORS(Output Record Separator)顾名思义就相当与输出的 RS。 每条记录在输出时候会用分隔符隔开 看下面的 ORS 的例子:

$ awk 'BEGIN{ORS="=";} {print;}' student-marksJones 2143 78 84 77=Gondrol 2321 56 58 45=RinRao 2122 38 37 65=Edwin 2537 78 67 45=Dayan 2415 30 47 20=

上面的脚本 输入文件的每条记录被 = 分隔开。 附:student-marks 便是上面的输出.

NR: 记录数变量

NR(Number of Record) 表示的是已经处理过的总记录数目 或者说行号(不一定是一个文件 可能是多个)。下面的例子 NR 表示行号 在 END 部分 NR 就是文件中的所有记录数目。

$ awk '{print "Processing Record - ",NR;}END {print NR, "Students Records are processed";}' student-marksProcessing Record - 1Processing Record - 2Processing Record - 3Processing Record - 4Processing Record - 55 Students Records are processed

NF:一条记录的记录数目

NF(Number for Field)表示的是 一条记录的字段的数目. 它在判断某条记录是否所有字段都存在时非常有用。 让观察 student-mark 文件如下:

$ cat student-marksJones 2143 78 84 77Gondrol 2321 56 58 45RinRao 2122 38 37Edwin 2537 78 67 45Dayan 2415 30 47

接着下面的Awk程序 打印了记录数(NR),以及该记录的字段数目: 因此可以非常容易的发现那些数据丢失了。

$ awk '{print NR,"->",NF}' student-marks1 -> 52 -> 53 -> 44 -> 55 -> 4

FILENAME: 当前输入文件的名字

FILENAME 表示当前正在输入的文件的名字。 AWK 可以接受读取很多个文件去处理。看下面的例子:

$ awk '{print FILENAME}' student-marksstudent-marksstudent-marksstudent-marksstudent-marksstudent-marks

在输入的文件的每一条记录都会输出该名字。

FNR: 当前输入文件的记录数目

当awk读取多个文件时 NR 代表的是当前输入所有文件的全部记录数 而 FNR 则是当前文件的记录数。如下面的例子:

$ awk '{print FILENAME, "FNR= ", FNR," NR= ", NR}' student-marks bookdetailsstudent-marks FNR= 1  NR= 1student-marks FNR= 2  NR= 2student-marks FNR= 3  NR= 3student-marks FNR= 4  NR= 4student-marks FNR= 5  NR= 5bookdetails FNR= 1  NR= 6bookdetails FNR= 2  NR= 7bookdetails FNR= 3  NR= 8bookdetails FNR= 4  NR= 9bookdetails FNR= 5  NR= 10

附: bookdetails 与 student-marks 内容一样 作例子. 可以看出来 NRFNR 的区别。

经常使用 NRFNR 结合来处理两个文件 比如有两个文件:

$ cat a.txt李四|000002张三|000001王五|000003赵六|000004$ cat b.txt000001|10000001|20000002|30000002|15000002|45000003|40000003|25000004|60

如果想作对应的话, 比如张三|000001|10

$ awk -F '|' 'NR == FNR{a[$2]=$1;} NR>FNR {print a[$1],"|", $0}' a.txt b.txt张三 | 000001|10张三 | 000001|20李四 | 000002|30李四 | 000002|15李四 | 000002|45王五 | 000003|40王五 | 000003|25赵六 | 000004|60

英文原文:http://www.thegeekstuff.com/2010/01/8-powerful-awk-built-in-variables-fs-ofs-rs-ors-nr-nf-filename-fnr/

译文 :http://shomy.top/2016/05/05/trans-8-powerful-awk-built-in-variables/