8 个有力的 Awk 内建变量

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.awk
BEGIN{
FS=":";
print "Name\tUserID\tGroupID\tHomeDirectory";
}
{
    print $1"\t"$3"\t"$4"\t"$6;
}
END {
    print NR,"Records Processed";
}

使用结果:

$ awk -f etc_passwd.awk /etc/passwd
Name    UserID  GroupID        HomeDirectory
gnats    41    41    /var/lib/gnats
libuuid    100    101    /var/lib/libuuid
syslog    101    102    /home/syslog
hplip    103    7    /var/run/hplip
avahi    105    111    /var/run/avahi-daemon
saned    110    116    /home/saned
pulse    111    117    /var/run/pulse
gdm    112    119    /var/lib/gdm
8 Records Processed

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

$ awk -F':' '{print $3,$4;}' /etc/passwd
41 41
100 101
101 102
103 7
105 111
110 116
111 117
112 119

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

$ awk -F':' 'BEGIN{OFS="=";} {print $3,$4;}' /etc/passwd
41=41
100=101
101=102
103=7
105=111
110=116
111=117
112=11

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

$ cat student.txt
Jones
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.txt输出两项内容:

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

在 student.awk 中,把每个学生的详细信息作为一条记录, 这是因为RS(记录分隔符)是被设置为两个换行符。并且因为 FS (字段分隔符)是一个换行符,所以一行就是一个字段。
ORS: 输出记录分隔符变量
ORS(Output Record Separator)顾名思义就相当与输出的 RS。 每条记录在输出时候会用分隔符隔开,看下面的 ORS 的例子:

$  awk 'BEGIN{ORS="=";} {print;}' student-marks
Jones 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-marks
Processing Record -  1
Processing Record -  2
Processing Record -  3
Processing Record -  4
Processing Record -  5
5 Students Records are processed

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

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

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

$ awk '{print NR,"->",NF}' student-marks
1 -> 5
2 -> 5
3 -> 4
4 -> 5
5 -> 4

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

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

在输入的文件的每一条记录都会输出该名字。
FNR: 当前输入文件的记录数目
当awk读取多个文件时,NR 代表的是当前输入所有文件的全部记录数,而 FNR 则是当前文件的记录数。如下面的例子:

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

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

经常使用 NR 与 FNR 结合来处理两个文件,比如有两个文件:

$ cat a.txt
李四|000002
张三|000001
王五|000003
赵六|000004

$ cat b.txt
000001|10
000001|20
000002|30
000002|15
000002|45
000003|40
000003|25
000004|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/

赞(2)

评论 抢沙发

评论前必须登录!

 

Linux 基础教程
Linux 简介Linux 安装Linux 云服务器Linux 系统启动过程Linux 系统目录结构Linux 忘记密码解决方法Linux 远程登录Linux 文件基本属性Linux 文件与目录管理Linux 用户和用户组管理Linux 磁盘管理Linux vi/vimlinux yum 命令VMware 安装 Centos7 超详细过程
Linux 命令
Linux 命令大全Linux cat命令Linux chattr命令Linux chgrp命令Linux chmod命令Linux chown命令Linux cksum命令Linux cmp命令Linux diff命令Linux diffstat命令Linux file命令Linux find命令Linux git命令Linux gitview命令Linux indent命令Linux cut命令Linux ln命令Linux less命令Linux locate命令Linux lsattr命令Linux mattrib命令Linux mc命令Linux mdel命令Linux mdir命令Linux mktemp命令Linux more命令Linux mmove命令Linux mread命令Linux mren命令Linux mtools命令Linux mtoolstest命令Linux mv 命令Linux od命令Linux paste命令Linux patch命令Linux rcp命令Linux rm命令Linux slocate命令Linux split命令Linux tee命令Linux tmpwatch命令Linux touch命令Linux umask命令Linux which命令Linux cp命令Linux whereis命令Linux mcopy命令Linux mshowfat命令Linux rhmask命令Linux scp命令Linux awk 命令Linux read 命令Linux updatedb 命令Linux col命令Linux colrm命令Linux comm命令Linux csplit命令Linux ed命令Linux egrep命令Linux ex命令Linux fgrep命令Linux fmt命令Linux fold命令Linux grep 命令Linux ispell命令Linux jed命令Linux joe命令Linux join命令Linux look命令Linux mtype命令Linux pico命令Linux rgrep命令Linux sed 命令Linux sort命令Linux spell命令Linux tr命令Linux expr命令Linux uniq 命令Linux wc命令Linux let 命令Linux lprm命令Linux lpr命令Linux lpq命令Linux lpd命令Linux bye命令Linux ftp命令Linux uuto命令Linux uupick命令Linux uucp命令Linux uucico命令Linux tftp命令Linux ncftp命令Linux ftpshut命令Linux ftpwho命令Linux ftpcount命令Linux cd命令Linux df命令Linux dirs命令Linux du命令Linux edquota命令Linux eject命令Linux mcd命令Linux mdeltree命令Linux mdu命令Linux mkdir命令Linux mlabel命令Linux mmd命令Linux mrd命令Linux mzip命令Linux pwd命令Linux quota命令Linux mount命令Linux mmount命令Linux rmdir命令Linux rmt命令Linux stat命令Linux tree命令Linux umount命令Linux ls命令Linux quotacheck命令Linux quotaoff命令Linux lndir命令Linux repquota命令Linux quotaon命令Linux badblocks命令Linux cfdisk命令Linux dd命令Linux e2fsck命令Linux ext2ed命令Linux fsck命令Linux fsck.minix命令Linux fsconf命令Linux fdformat命令Linux hdparm命令Linux mformat命令Linux mkbootdisk命令Linux mkdosfs命令Linux mke2fs命令Linux mkfs.ext2命令Linux mkfs.msdos命令Linux mkinitrd命令Linux mkisofs命令Linux mkswap命令Linux mpartition命令Linux swapon命令Linux symlinks命令Linux sync命令Linux mbadblocks命令Linux mkfs.minix命令Linux fsck.ext2命令Linux fdisk命令Linux losetup命令Linux mkfs命令Linux sfdisk命令Linux swapoff命令Linux apachectl命令Linux arpwatch命令Linux dip命令Linux getty命令Linux mingetty命令Linux uux命令Linux telnet命令Linux uulog命令Linux uustat命令Linux ppp-off命令Linux netconfig命令Linux nc命令Linux httpd命令Linux ifconfig命令Linux minicom命令Linux mesg命令Linux dnsconf命令Linux wall命令Linux netstat命令Linux ping命令Linux pppstats命令Linux samba命令Linux setserial命令Linux talk命令Linux traceroute命令Linux tty命令Linux newaliases命令Linux uuname命令Linux netconf命令Linux write命令Linux statserial命令Linux efax命令Linux pppsetup命令Linux tcpdump命令Linux ytalk命令Linux cu命令Linux smbd命令Linux testparm命令Linux smbclient命令Linux shapecfg命令Linux adduser命令Linux chfn命令Linux useradd命令Linux date命令Linux exit命令Linux finger命令Linux fwhios命令Linux sleep命令Linux suspend命令Linux groupdel命令Linux groupmod命令Linux halt命令Linux kill命令Linux last命令Linux lastb命令Linux login命令Linux logname命令Linux logout命令Linux ps命令Linux nice命令Linux procinfo命令Linux top命令Linux pstree命令Linux reboot命令Linux rlogin命令Linux rsh命令Linux sliplogin命令Linux screen命令Linux shutdown命令Linux rwho命令Linux sudo命令Linux gitps命令Linux swatch命令Linux tload命令Linux logrotate命令Linux uname命令Linux chsh命令Linux userconf命令Linux userdel命令Linux usermod命令Linux vlock命令Linux who命令Linux whoami命令Linux whois命令Linux newgrp命令Linux renice命令Linux su命令Linux skill命令Linux w命令Linux id命令Linux groupadd 命令Linux free命令Linux reset命令Linux clear命令Linux alias命令Linux dircolors命令Linux aumix命令Linux bind命令Linux chroot命令Linux clock命令Linux crontab 命令Linux declare命令Linux depmod命令Linux dmesg命令Linux enable命令Linux eval命令Linux export命令Linux pwunconv命令Linux grpconv命令Linux rpm命令Linux insmod命令Linux kbdconfig命令Linux lilo命令Linux liloconfig命令Linux lsmod命令Linux minfo命令Linux set命令Linux modprobe命令Linux ntsysv命令Linux mouseconfig命令Linux passwd命令Linux pwconv命令Linux rdate命令Linux resize命令Linux rmmod命令Linux grpunconv命令Linux modinfo命令Linux time命令Linux setup命令Linux sndconfig命令Linux setenv命令Linux setconsole命令Linux timeconfig命令Linux ulimit命令Linux unset命令Linux chkconfig命令Linux apmd命令Linux hwclock命令Linux mkkickstart命令Linux fbset命令Linux unalias命令Linux SVGATextMode命令Linux gpasswd 命令Linux ar命令Linux bunzip2命令Linux bzip2命令Linux bzip2recover命令Linux gunzip命令Linux unarj命令Linux compress命令Linux cpio命令Linux dump命令Linux uuencode命令Linux gzexe命令Linux gzip命令Linux lha命令Linux restore命令Linux tar命令Linux uudecode命令Linux unzip命令Linux zip命令Linux zipinfo命令Linux setleds命令Linux loadkeys命令Linux rdev命令Linux dumpkeys命令Linux MAKEDEV命令Linux poweroff 命令Linux bc 命令Linux tail 命令Linux xargs 命令Linux 常用命令全拼AWK 工作原理AWK 数组AWK 条件语句与循环AWK 用户自定义函数AWK 内置函数8 个有力的 Awk 内建变量
Linux 问答
Nano和VIM编辑器的区别Bash脚本中Zsh和Bash的区别Ubuntu中APT和DPKG的区别Linux中桌面环境和窗口管理器的区别Owncloud和Nextcloud的区别wget和curl的区别UNIX系统中用户cpu时间和系统cpu时间的区别KornShell 和 BashShell 的区别Linux下Ext4和Btrfs文件系统的区别片上系统SoC 与 单板计算机SBC的区别用户级线程和内核级线程的区别优先级倒置和优先级继承的区别MMU和MPU有什么区别UEFI(统一可扩展固件接口)与BIOS的区别不同类型的RAM(随机存取内存)Ubuntu 和 Red Hat Linux 的区别Ubuntu 和 Kali Linux 的区别Jumpshare 和 Ubuntu One 的区别Ubuntu和Fedora的区别RAID 1 和 RAID 5的区别比特币和区块链的区别Arch Linux 和 Kali Linux 的区别Fedora 和 Kali Linux 的区别硬拷贝和软拷贝的区别RAID 5 和 RAID 10的区别本地文件系统 (LFS) 和分布式文件系统 (DFS) 的区别RPA 和 Selenium 的区别Linux 和 OS/2的区别Linux 和 Plan 9 的区别硬盘驱动器和闪存驱动器的区别中断和异常的区别Arduino和树莓派的区别FAT32、exFAT 和 NTFS 文件系统的区别FCFS和优先级CPU调度的区别Linux和Unix的区别Python 和 Bash 的区别fork() 和 exec()的区别先到先服务 (FCFS) 和最长作业优先 (LJF) CPU 调度算法的区别最长作业优先 (LJF) 和循环 (RR) 调度算法的区别多道程序,多任务,多线程和多处理的区别管道和消息队列的区别优先级调度和循环 (RR) CPU 调度的区别优先级调度和最短作业优先 (SJF) CPU 调度的区别UEFI和BIOS的区别fork()和vfork()的区别