记录:awk把每一个以换行符结束的行称为一个记录。
记录分隔符RS/ORS:默认的输入和输出的分隔符都是回车,保存在内建变量ORS和RS中。
变量$0:它指的是整条记录。如$ awk '{print $0}' test将输出test文件中的所有记录。
变量NR:一个计数器,每处理完一条记录,NR的值就增加1。如$ awk '{print NR,$0}' test将输出test文件中所有记录,并在记录前显示记录号。
域$X:记录中每个单词称做“域”,默认情况下以空格或tab分隔。awk可跟踪域的个数,并在内建变量NF中保存该值。
域分隔符FS:内建变量FS保存输入域分隔符的值,默认是空格或tab。我们可以通过-F命令行选项修改FS的值。符写成放到方括号中,如$awk -F'[:\t]' '{print $1,$3}' test,表示以空格、冒号和tab作为分隔符。
输出域的分隔符OFS:默认是一个空格,保存在OFS中。如$ awk -F: '{print $1,$5}' test,$1和$5间的逗号就是OFS的值。
不匹配
有时要浏览信息并抽取不匹配操作的记录,与~相反的符号是!~,意即不匹配。
# awk '$0 !~ /Brown/' grade.txt
# awk '{if($4~/Brown/) print $0}' grade.txt
设置大小写
为查询大小写信息,可使用[ ]符号。在测试正则表达式时提到可匹配[ ]内任意字符或单词,因此若查询文件中级别为green的所有记录,不论其大小写,表达式应为'/[Gg]reen/'
# awk '/[Gg]reen/' grade.txt
任意字符
抽取名字,其记录第一域的第四个字符是a,使用句点.。表达式/^...a/意为行首前三个字符任意,第四个是a,尖角符号代表行首。
# awk '$1 ~ /^...a/' grade.txt
或关系匹配
使用竖线符|,意为匹配|两边模式之一。注意,使用竖线符时,语句必须用圆括号括起来。
# awk '$0 ~/(Yellow|Brown)/' grade.txt
使用这种方法在查询级别为Green或green时,可以得到与使用[ ]表达式相同的结果。
awk内置变量
ARGC:命令行参数个数
ARGV:命令行参数排列
ARGIND 当前被处理文件的ARGV标志符
ENVIRON:支持队列中系统环境变量的使用
FILENAME:awk浏览的文件名
FNR:浏览文件的记录数
FS:设置输入域分隔符,等价于命令行-F选项
NF:浏览记录的域个数
NR:已读的记录数。要快速查看记录个数,应使用NR。
OFS:输出域分隔符
ORS:输出记录分隔符
RS:控制记录分隔符
ARGC支持命令行中传入awk脚本的参数个数。ARGV是ARGC的参数排列数组,其中每一元素表示为ARGV [n],n为期望访问的命令行参数。
ENVIRON支持系统设置的环境变量,要访问单独变量,使用实际变量名,例如ENVIRON ["EDITOR"]="Vi"。
FILENAME支持awk脚本实际操作的输入文件。因为awk可以同时处理许多文件,因此如果访问了这个变量,将告之系统目前正在浏览的实际文件。
FNR支持awk目前操作的记录数。其变量值小于等于NR。如果脚本正在访问许多文件,每一新输入文件都将重新设置此变量。
FS用来在awk中设置域分隔符,与命令行中-F选项功能相同。缺省情况下为空格。如果用逗号来作域分隔符,设置FS=","。
NF支持记录域个数,在记录被读之后再设置。
OFS允许指定输出域分隔符,缺省为空格。如果想设置为#,写入OFS="#"。
ORS为输出记录分隔符,缺省为新行(\n)。
RS是记录分隔符,缺省为新行(\n)。
文件长度相加
在目录中查看文件时,如果想快速查看所有文件的长度及其总和,但要排除子目录,使用ls -l命令,然后管道输出到awk,awk首先剔除首字符为d(使用正则表达式)的记录,然后将文件长度列相加,并输出每一文件长度及在END部分输出所有文件的长度。
本例中,首先用ls -l命令查看一下文件属性。注意第二个文件属性首字符为d,说明它是一个目录,文件长度是第5列,文件名是第9列。如果系统不是这样排列文件名及其长度,应适时加以改变。
下面的正则表达式表明必须匹配行首,并排除字符d,表达式为^[^d]。使用此模式打印文件名及其长度,然后将各长度相加放入变量tot中。
$ls -l | awk '/^[^d]/ {print $9"\t"$5} {tot+=$5} END {print "total KB:" tot}'
记录分隔符RS/ORS:默认的输入和输出的分隔符都是回车,保存在内建变量ORS和RS中。
变量$0:它指的是整条记录。如$ awk '{print $0}' test将输出test文件中的所有记录。
变量NR:一个计数器,每处理完一条记录,NR的值就增加1。如$ awk '{print NR,$0}' test将输出test文件中所有记录,并在记录前显示记录号。
域$X:记录中每个单词称做“域”,默认情况下以空格或tab分隔。awk可跟踪域的个数,并在内建变量NF中保存该值。
域分隔符FS:内建变量FS保存输入域分隔符的值,默认是空格或tab。我们可以通过-F命令行选项修改FS的值。符写成放到方括号中,如$awk -F'[:\t]' '{print $1,$3}' test,表示以空格、冒号和tab作为分隔符。
输出域的分隔符OFS:默认是一个空格,保存在OFS中。如$ awk -F: '{print $1,$5}' test,$1和$5间的逗号就是OFS的值。
元字符
这里是awk中正则表达式匹配操作中经常用到的字符。
\ ^ $. [] | () * + ?
这里有两个字符只适用于awk而不适用于grep或sed。它们是:
+:使用+匹配一个或多个字符。
?:匹配模式出现频率。例如使用/X Y?Z/匹配X Y Z或Y Z。
匹配
为使一域号匹配正则表达式,使用符号'~'后紧跟正则表达式,也可以用if语句。awk中if后面的条件用()括起来。
表达式{if($4~/brown/) print}意即如果field-4包含brown,打印它。
匹配记录找到时,如果不特别声明, awk缺省打印整条记录。
精确匹配
为精确匹配48,使用等号==,并用单引号括起条件。例如$3
# awk '$3=="48" {print$0}' grade.txt
不匹配
有时要浏览信息并抽取不匹配操作的记录,与~相反的符号是!~,意即不匹配。
# awk '$0 !~ /Brown/' grade.txt
# awk '{if($4~/Brown/) print $0}' grade.txt
设置大小写
为查询大小写信息,可使用[ ]符号。在测试正则表达式时提到可匹配[ ]内任意字符或单词,因此若查询文件中级别为green的所有记录,不论其大小写,表达式应为'/[Gg]reen/'
# awk '/[Gg]reen/' grade.txt
任意字符
抽取名字,其记录第一域的第四个字符是a,使用句点.。表达式/^...a/意为行首前三个字符任意,第四个是a,尖角符号代表行首。
# awk '$1 ~ /^...a/' grade.txt
或关系匹配
使用竖线符|,意为匹配|两边模式之一。注意,使用竖线符时,语句必须用圆括号括起来。
# awk '$0 ~/(Yellow|Brown)/' grade.txt
使用这种方法在查询级别为Green或green时,可以得到与使用[ ]表达式相同的结果。
行首
行首,不必总是使用域号。如果查询文本文件行首包含M的代码,可简单使用下面^符号:
# awk '/^M/' grade.txt
复合表达式
复合表达式即为模式间通过使用下述各表达式互相结合起来的表达式:
&& AND : 语句两边必须同时匹配为真。
|| OR:语句两边同时或其中一边匹配为真。
! 非求逆
awk内置变量
ARGC:命令行参数个数
ARGV:命令行参数排列
ARGIND 当前被处理文件的ARGV标志符
ENVIRON:支持队列中系统环境变量的使用
FILENAME:awk浏览的文件名
FNR:浏览文件的记录数
FS:设置输入域分隔符,等价于命令行-F选项
NF:浏览记录的域个数
NR:已读的记录数。要快速查看记录个数,应使用NR。
OFS:输出域分隔符
ORS:输出记录分隔符
RS:控制记录分隔符
ARGC支持命令行中传入awk脚本的参数个数。ARGV是ARGC的参数排列数组,其中每一元素表示为ARGV [n],n为期望访问的命令行参数。
ENVIRON支持系统设置的环境变量,要访问单独变量,使用实际变量名,例如ENVIRON ["EDITOR"]="Vi"。
FILENAME支持awk脚本实际操作的输入文件。因为awk可以同时处理许多文件,因此如果访问了这个变量,将告之系统目前正在浏览的实际文件。
FNR支持awk目前操作的记录数。其变量值小于等于NR。如果脚本正在访问许多文件,每一新输入文件都将重新设置此变量。
FS用来在awk中设置域分隔符,与命令行中-F选项功能相同。缺省情况下为空格。如果用逗号来作域分隔符,设置FS=","。
NF支持记录域个数,在记录被读之后再设置。
OFS允许指定输出域分隔符,缺省为空格。如果想设置为#,写入OFS="#"。
ORS为输出记录分隔符,缺省为新行(\n)。
RS是记录分隔符,缺省为新行(\n)。
文件长度相加
在目录中查看文件时,如果想快速查看所有文件的长度及其总和,但要排除子目录,使用ls -l命令,然后管道输出到awk,awk首先剔除首字符为d(使用正则表达式)的记录,然后将文件长度列相加,并输出每一文件长度及在END部分输出所有文件的长度。
本例中,首先用ls -l命令查看一下文件属性。注意第二个文件属性首字符为d,说明它是一个目录,文件长度是第5列,文件名是第9列。如果系统不是这样排列文件名及其长度,应适时加以改变。
下面的正则表达式表明必须匹配行首,并排除字符d,表达式为^[^d]。使用此模式打印文件名及其长度,然后将各长度相加放入变量tot中。
$ls -l | awk '/^[^d]/ {print $9"\t"$5} {tot+=$5} END {print "total KB:" tot}'