awk 总结

概述

awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理
awk工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键" 或 "[tab]键"


awk命令形式:
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
[-F|-f|-v] 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
' ' 引用代码块
BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
// 匹配代码块,可以是字符串或正则表达式
{} 命令代码块,包含一条或多条命令
; 多条命令使用分号分隔
END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

特殊要点:
$0 表示整个当前行
$1 每行第一个字段
NF 字段数量变量
NR 每行的记录号,多文件记录递增
FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始
\t 制表符
\n 换行符
FS BEGIN时定义分隔符
RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~ 匹配,与==相比不是精确比较
!~ 不匹配,不精确比较
== 等于,必须全部相等,精确比较
!= 不等于,精确比较
&&  逻辑与
|| 逻辑或
+ 匹配时表示1个或1个以上
/[0-9][0-9]+/ 两个或两个以上数字
/[0-9][0-9]*/ 一个或一个以上数字
FILENAME 文件名
OFS 输出字段分隔符, 默认也是空格,可以改为制表符等
ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F'[:#/]' 定义三个分隔符

print & $0
print 是awk打印指定内容的主要命令
awk '{print}' /etc/passwd == awk '{print $0}' /etc/passwd
awk '{print " "}' /etc/passwd //不输出passwd的内容,而是输出相同个数的空行,进一步解释了awk是一行一行处理文本
awk '{print "a"}' /etc/passwd //输出相同个数的a行,一行只有一个a字母
awk -F":" '{print $1}' /etc/passwd
awk -F: '{print $1; print $2}' /etc/passwd //将每一行的前二个字段,分行输出,进一步理解一行一行处理文本
awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd //输出字段1,3,6,以制表符作为分隔符

-f指定脚本文件
awk -f script.awk file
BEGIN{
FS=":"
}
{print $1} //效果与awk -F":" '{print $1}'相同,只是分隔符使用FS在代码自身中指定

awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test
I find 4 blank lines.
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}' //计算文件大小
total size is 17487

-F指定分隔符
$1 指指定分隔符后,第一个字段,$3第三个字段, \t是制表符
一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格
awk -F":" '{print $1}' /etc/passwd
awk -F":" '{print $1 $3}' /etc/passwd //$1与$3相连输出,不分隔
awk -F":" '{print $1,$3}' /etc/passwd //多了一个逗号,$1与$3使用空格分隔
awk -F":" '{print $1 " " $3}' /etc/passwd //$1与$3之间手动添加空格分隔
awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd //自定义输出
awk -F: '{print NF}' /etc/passwd //显示每行有多少字段
awk -F: '{print $NF}' /etc/passwd //将每行第NF个字段的值打印出来
awk -F: 'NF==4 {print }' /etc/passwd //显示只有4个字段的行
awk -F: 'NF>2{print $0}' /etc/passwd //显示每行字段数量大于2的行
awk '{print NR,$0}' /etc/passwd //输出每行的行号
awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd //依次打印行号,字段数,最后字段值,制表符,每行内容
awk -F: 'NR==5{print}' /etc/passwd //显示第5行
awk -F: 'NR==5 || NR==6{print}' /etc/passwd //显示第5行和第6行
route -n|awk 'NR!=1{print}' //不显示第一行

//匹配代码块
//纯字符匹配 !//纯字符不匹配 ~//字段值匹配 !~//字段值不匹配 ~/a1|a2/字段值匹配a1或a2
awk '/mysql/' /etc/passwd
awk '/mysql/{print }' /etc/passwd
awk '/mysql/{print $0}' /etc/passwd //三条指令结果一样
awk '!/mysql/{print $0}' /etc/passwd //输出不匹配mysql的行
awk '/mysql|mail/{print}' /etc/passwd
awk '!/mysql|mail/{print}' /etc/passwd
awk -F: '/mail/,/mysql/{print}' /etc/passwd //区间匹配
awk '/[2][7][7]*/{print $0}' /etc/passwd //匹配包含27为数字开头的行,如27,277,2777...
awk -F: '$1~/mail/{print $1}' /etc/passwd //$1匹配指定内容才显示
awk -F: '{if($1~/mail/) print $1}' /etc/passwd //与上面相同
awk -F: '$1!~/mail/{print $1}' /etc/passwd //不匹配
awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd

IF语句
必须用在{}中,且比较内容用()扩起来
awk -F: '{if($1~/mail/) print $1}' /etc/passwd //简写
awk -F: '{if($1~/mail/) {print $1}}' /etc/passwd //全写
awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd //if...else...


条件表达式
== != > >=
awk -F":" '$1=="mysql"{print $3}' /etc/passwd
awk -F":" '{if($1=="mysql") print $3}' /etc/passwd //与上面相同
awk -F":" '$1!="mysql"{print $3}' /etc/passwd //不等于
awk -F":" '$3>1000{print $3}' /etc/passwd //大于
awk -F":" '$3>=100{print $3}' /etc/passwd //大于等于
awk -F":" '$3<1{print $3}' /etc/passwd //小于
awk -F":" '$3<=1{print $3}' /etc/passwd //小于等于

逻辑运算符
&& ||
awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd //逻辑与,$1匹配mail,并且$3>8
awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd
awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd //逻辑或
awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd

数值运算
awk -F: '$3 > 100' /etc/passwd
awk -F: '$3 > 100 || $3 < 5' /etc/passwd
awk -F: '$3+$4 > 200' /etc/passwd
awk -F: '/mysql|mail/{print $3+10}' /etc/passwd //第三个字段加10打印
awk -F: '/mysql/{print $3-$4}' /etc/passwd //减法
awk -F: '/mysql/{print $3*$4}' /etc/passwd //求乘积
awk '/MemFree/{print $2/1024}' /proc/meminfo //除法
awk '/MemFree/{print int($2/1024)}' /proc/meminfo //取整

输出分隔符OFS
awk '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
awk '$6 ~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
//输出字段6匹配WAIT的行,其中输出每行行号,字段4,5,6,并使用制表符分割字段

输出处理结果到文件
①在命令代码块中直接输出 route -n|awk 'NR!=1{print > "./fs"}'
②使用重定向进行输出 route -n|awk 'NR!=1{print}' > ./fs

格式化输出
netstat -anp|awk '{printf "%-8s %-8s %-10s\n",$1,$2,$3}'
printf表示格式输出
%格式化输出分隔符
-8长度为8个字符
s表示字符串类型
打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8),
第三个字段输出字符串类型(长度为10)
netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s \n",$1,$2,$3}'
netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s %-10s \n",NR,$1,$2,$3}'

IF语句
awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd
small
small
small
large
small
small
awk -F: 'BEGIN{A=0;B=0} {if($3>100) {A++; print "large"} else {B++; print "small"}} END{print A,"\t",B}' /etc/passwd
//ID大于100,A加1,否则B加1
awk -F: '{if($3<100) next; else print}' /etc/passwd //小于100跳过,否则显示
awk -F: 'BEGIN{i=1} {if(i<NF) print NR,NF,i++ }' /etc/passwd
awk -F: 'BEGIN{i=1} {if(i<NF) {print NR,NF} i++ }' /etc/passwd
另一种形式
awk -F: '{print ($3>100 ? "yes":"no")}' /etc/passwd
awk -F: '{print ($3>100 ? $3":\tyes":$3":\tno")}' /etc/passwd

while语句
awk -F: 'BEGIN{i=1} {while(i<NF) print NF,$i,i++}' /etc/passwd
7 root 1
7 x 2
7 0 3
7 0 4
7 root 5
7 /root 6

数组
netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) print i,"\t",a[i]}'
netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) printf "%-20s %-10s %-5s \n", i,"\t",a[i]}'
9523 1
9929 1
LISTEN 6
7903 1
3038/cupsd 1
7913 1
10837 1
9833 1

应用1
awk -F: '{print NF}' helloworld.sh //输出文件每行有多少字段
awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh //输出前5个字段
awk -F: '{print $1,$2,$3,$4,$5}' OFS='\t' helloworld.sh //输出前5个字段并使用制表符分隔输出
awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='\t' helloworld.sh //制表符分隔输出前5个字段,并打印行号

应用2
awk -F'[:#]' '{print NF}' helloworld.sh //指定多个分隔符: #,输出每行多少字段
awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS='\t' helloworld.sh //制表符分隔输出多字段

应用3
awk -F'[:#/]' '{print NF}' helloworld.sh //指定三个分隔符,并输出每行字段数
awk -F'[:#/]' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}' helloworld.sh //制表符分隔输出多字段

应用4
计算/home目录下,普通文件的大小,使用KB作为单位
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",sum/1024,"KB"}'
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",int(sum/1024),"KB"}' //int是取整的意思

应用5
统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少
netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i," ",sum[i]}'

应用6
统计/home目录下不同用户的普通文件的总数是多少?
ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i," ",sum[i]}'
mysql 199
root 374
统计/home目录下不同用户的普通文件的大小总size是多少?
ls -l|awk 'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s \n",i," ",sum[i]/1024/1024,"MB"}'

应用7
输出成绩表
awk 'BEGIN{math=0;eng=0;com=0;printf "Lineno. Name No. Math English Computer Total\n";printf "------------------------------------------------------------\n"}{math+=$3; eng+=$4; com+=$5;printf "%-8s %-7s %-7s %-7s %-9s %-10s %-7s \n",NR,$1,$2,$3,$4,$5,$3+$4+$5} END{printf "------------------------------------------------------------\n";printf "%-24s %-7s %-9s %-20s \n","Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s \n","Avg:",math/NR,eng/NR,com/NR}' test0

[root@localhost home]# cat test0
Marry 2143 78 84 77
Jack 2321 66 78 45
Tom 2122 48 77 71
Mike 2537 87 97 95
Bob 2415 40 57 62

一、空行

1、将每行后面都添加一个空行

awk '1; { print "" }'
这是怎么意思呢?一个单行awk命令,其实也是一个用awk语言写的程序,每个awk程序,都是由一系列的“匹配模式 { 执行动作 }”语句所组成的。在这个例子里面,有两个语句,“1”和“{print “”}”。在每个“匹配模式——执行动作”语句中,模式和动作都是可以被省略的。如果匹配模式被省略,那么预定的动作将会对输入文件的每一行执行。如果动作被省略,那么就默认会执行{print }。所以,这个单行awk语句等同于下面的语句:

awk '1 {print } {print ""}'
动作只有在匹配模式的值为真的时候才会执行。因为“1”永远为真,所以,这个例子也可以写成下面的形式

awk '{print } {print ""}'
awk中每条print语句后都默认会输出一个ORS变量(Output Record Separator,即输出行分隔符,默认为换行符)。第一个不带参数的print语句,等同于print $0,其中$0是代表整行内容的变量。第二个print语句什么也不输出,但是鉴于print语句后都会被自动加上ORS变量,这句的作用就是输出一个新行。于是每行后面加空行的目的就达到了。

 

2、另外一种添加空行的方法

awk 'BEGIN { ORS="nn" }; 1'
BEGIN是一个特殊的模式,后面所接的内容,会在文件被读入前执行。这里,对ORS变量进行了重新定义,将一个换行符改成了两个。后面的“1”,同样等价于{print },这样就达到了在每行后用新的ORS添加空行的目的。

 

3、在每个非空的行后面添加空行

awk 'NF {print $0 "n"}'
这个语句里面用到了一个新的变量,NF(number of fields),即本行被分割成的字段的数目。例如,“this is a test”,会被awk分割成4个词语,NF的值就为4。当遇到空行,分割后的字段数为0,NF为0,后面的匹配动作就不会被执行。这条语句,可以理解成“如果这一行可以分割成任意大于0的部分,那么输出当前行以及一个换行符”。

 

4、在每行后添加两个空行

awk '1; {print "n"}'
这一语句与前面的很相似。“1”可以理解为{print },所以整个句子可以改写为

awk '{print ; print "n"}'
它首先输出当前行,然后再输出一个换行符以及一个结束print语句的ORS,也就是另外一个换行符。

 

二、行号

5、为每个文件的内容添加行号

awk '{ print FNR "t" $0 }'
这个awk程序在每行的内容前添加了一个变量FNR的输出,并用一个制表符进行分隔。FNR(File Number of Row)这个变量记录了当前行在当前文件中的行数。在处理下一个文件时,这个变量会被重置为0。

 

6、为所有文件的所有行统一添加行号

awk '{print NR "t" $0}'
这一句与上一例基本一样,除了使用的行号变量是NR(Number of Row),这个变量不会在处理新文件的时候被重置。所以说,如果你有2个文件,一个10行一个12行,那这个变量会从1一直变到22。

7、用更漂亮的样式添加行号

awk '{printf("%5d : %sn", FNR, $0)}'
这个例子用了printf函数来自定义输出样式,它所接受的参数与标准C语言的printf函数基本一致。需要注意的是,printf后不会被自动添加ORS,所以你需要自己指定换行。这个语句指定了行号会右对齐,然后是一个空格和冒号,接着是当前行的内容。

8、为文件中的非空行添加行号

awk 'NF { $0=++a " :" $0}; {print }'
awk的变量都是自动定义的:你第一次用到某个变量的时候它就自动被定义了。这个语句在每次遇到一个非空行的时候先把一个变量a加1,然后把a的数值添加到行首,然后输出当前行的内容。

 

三、计算

9、计算文件行数(模拟 wc -l)

awk 'END {print NR}'
END是另外一个不会被检验是否为真的模式,后面的动作会在整个文件被读完后进行。这里是输出最终的行号,即文件的总行数。

 

10、对每行求和

awk '{s=0;for (i=0;i<NF;i++) s=s+$i; print s}'
awk有些类似C语言的语法,比如这里的for (;;;){ ... }循环。这句命令会让程序遍历所有NF个字段,并把字段的总和存在变量s中,最后输出s的数值并处理下一行。

 

11、对所有行所有字段求和

awk '{for (i=0;i<NF;i++) s=s+$i; END {print s+0}'
这个例子与上一个基本一致,除了输出的是所有行所有字段的和。由于变量会被自动定义,s只需要定义一次,故而不需要把s定义成0。另外需要注意的是,它输出{print s+0}而非{print s},这是因为如果文件为空,s不会被定义就不会有任何输出了,输出s+0可以保证在这种情况下也会输出更有意义的0。

12、将所有字段替换为其绝对值

awk '{ for (i = 1; i <= NF; i++) if ($i < 0) $i = -$i; print }'
这条语句用了C语言的另外两个特性,一个是if (...) {...}结构,另外就是省略了大括号。它检查对每一行,检查每个字段的值是否小于0,如果值小于0,则将其改为正数。字段名可以间接地用变量的形式引用,如i=5;$i='hello'会将第5个字段的内容置为hello。

下面的是将这条语句完整的写出来的形式。print语句会在行中所有字段被改为正数后执行。

awk '{
for (i = 1; i <= NF; i++) {
if ($i < 0) {
$i = -$i;
}
}
print
}'
13、计算文件中的总字段(单词)数

awk '{total=total+NF};END {print total+0}'
这个命令匹配所有的行,并不断的把行中的字段数累加到变量total。执行完成上述动作后,输出total的数值。

注意:不是字母个数。

14、输出含有单词Beth的行的数目

awk '/Beth/ {n++}; END {print n+0}'
这个例子含有两个语句。第一句找出匹配/Beth/的行,并对变量n进行累加。在/…/之间的内容为正则表达式,/Beth/匹配所有含有“Beth”的单词(它不仅匹配Beth,同样也匹配Bethe)。第二句在文件处理完成后输出n的数值。这里用n+0是为了让n为0 的情况下输出0而不是一个空行。

15、寻找第一个字段为数字且最大的行

awk '$1 > max { max=$1; maxline=$0 }; END { print max, maxline }'
这个例子用变量max记录第一个字段的最大值,并把第一个字段最大的行的内容存在变量maxline中。在循环终止后,输出max和maxline的内容。注意:如果在数字都为负数的情况下,这个例子就不能用了,下面的是修改过的版本

awk 'NR == 1 { max = $1; maxline = $0; next; } $1 > max { max=$1; maxline=$0 }; END { print max, maxline }'
16、在每一行前添加输出该行的字段数

awk '{print NF ":" $0}'
这个例子仅仅是在逐行输出字段数NF,一个冒号,以及该行的内容。

17、输出每行的最后一个字段

awk '{print $NF}'
awk里面的字段可以用变量的形式引用。这一句输出第NF个字段的内容,而NF就是该行的字段数。

18、打印最后一行的最后一个字段

awk '{ field = $NF };END {print field}'
这个例子用field记录最后一个字段的内容,并在循环后输出field的内容。

这里是一个更好的版本。它更常用、更简洁也更高效:

awk 'END {print $NF}'
19、输出所有字段数大于4的行

awk 'NF > 4'
这个例子省略了要执行的动作。如前所述,省略动作等价于{print}。

20、输出所有最后一个字段大于4的行

awk '$NF > 4'
这个例子用$NF引用最后一个字段,如果它的数值大于4,那么就输出。


linux下awk内置函数的使用(split/substr/length)

一、split 初始化和类型强制
awk的内建函数split允许你把一个字符串分隔为单词并存储在数组中。你可以自己定义域分隔符或者使用现在FS(域分隔符)的值。
格式:
split (string, array, field separator)
split (string, array) -->如果第三个参数没有提供,awk就默认使用当前FS值。

例子:
例1:替换分隔符
1
2
3
time="12:34:56"
out=`echo $time | awk '{split($0,a,":");print a[1],a[2],a[3]}'`
echo $out
例2:计算指定范围内的和(计算每个人1月份的工资之和)

1
2
3
4
5
6
7
8
9
10
[root@test ~]# cat test.txt
Tom   2012-12-11 car 53000
John   2013-01-13 bike 41000
vivi 2013-01-18 car 42800
Tom   2013-01-20 car 32500
John   2013-01-28 bike 63500
[root@test ~]# awk '{split($2,a,"-");if(a[2]==01){b[$1]+=$4}}END{for(i in b)print i,b[i]}' test.txt
vivi 2800
Tom2500
John4500
二、substr 截取字符串

返回从起始位置起,指定长度之子字符串;若未指定长度,则返回从起始位置到字符串末尾的子字符串。
格式:
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分
例子:
1
2
[root@test ~]# echo "123" | awk '{print substr($0,1,1)}'
1
解释:

awk -F ',' '{print substr($3,6)}' ---> 表示是从第3个字段里的第6个字符开始,一直到设定的分隔符","结束.
substr($3,10,8) ---> 表示是从第3个字段里的第10个字符开始,截取8个字符结束.
substr($3,6) ---> 表示是从第3个字段里的第6个字符开始,一直到结尾

三、length 字符串长度
length函数返回没有参数的字符串的长度。length函数返回整个记录中的字符数。
1
2
[root@test ~]# echo "123" | awk '{print length}'
3
四、gsub函数
gsub函数则使得在所有正则表达式被匹配的时候都发生替换。gsub(regular expression, subsitution string, target string);简称 gsub(r,s,t)。

举例:把一个文件里面所有包含 abc 的行里面的 abc 替换成 def,然后输出第一列和第三列

1
awk '$0 ~ /abc/ {gsub("abc", "def", $0); print $1, $3}' abc.txt
五、正则表达式
字符 功能
+ 指定如果一个或多个字符或扩展正则表达式的具体值(在 +(加号)前)在这个字符串中,则字符串匹配。命令行:
awk '/smith+ern/' testfile

将包含字符 smit,后跟一个或多个 h 字符,并以字符 ern 结束的字符串的任何记录打印至标准输出。此示例中的输出是:

smithern, harry smithhern, anne

? 指定如果零个或一个字符或扩展正则表达式的具体值(在 ?(问号)之前)在字符串中,则字符串匹配。命令行:
awk '/smith?/' testfile

将包含字符 smit,后跟零个或一个 h 字符的实例的所有记录打印至标准输出。此示例中的输出是:

smith, alan smithern, harry smithhern, anne smitters, alexis

| 指定如果以 |(垂直线)隔开的字符串的任何一个在字符串中,则字符串匹配。命令行:
awk '/allen | alan /' testfile

将包含字符串 allen 或 alan 的所有记录打印至标准输出。此示例中的输出是:

smiley, allen smith, alan

( ) 在正则表达式中将字符串组合在一起。命令行:
awk '/a(ll)?(nn)?e/' testfile

将具有字符串 ae 或 alle 或 anne 或 allnne 的所有记录打印至标准输出。此示例中的输出是:

smiley, allen smithhern, anne

{m} 指定如果正好有 m 个模式的具体值位于字符串中,则字符串匹配。命令行:
awk '/l{2}/' testfile

打印至标准输出

smiley, allen

{m,} 指定如果至少 m 个模式的具体值在字符串中,则字符串匹配。命令行:
awk '/t{2,}/' testfile

打印至标准输出:

smitters, alexis

{m, n} 指定如果 m 和 n 之间(包含的 m 和 n)个模式的具体值在字符串中(其中m<= n),则字符串匹配。命令行:
awk '/er{1, 2}/' testfile

打印至标准输出:

smithern, harry smithern, anne smitters, alexis

[String] 指定正则表达式与方括号内 String 变量指定的任何字符匹配。命令行:
awk '/sm[a-h]/' testfile

将具有 sm 后跟以字母顺序从 a 到 h 排列的任何字符的所有记录打印至标准输出。此示例的输出是:

smawley, andy

[^ String] 在 [ ](方括号)和在指定字符串开头的 ^ (插入记号) 指明正则表达式与方括号内的任何字符不匹配。这样,命令行:
awk '/sm[^a-h]/' testfile

打印至标准输出:

smiley, allen smith, alan smithern, harry smithhern, anne smitters, alexis

~,!~ 表示指定变量与正则表达式匹配(代字号)或不匹配(代字号、感叹号)的条件语句。命令行:
awk '$1 ~ /n/' testfile

将第一个字段包含字符 n 的所有记录打印至标准输出。此示例中的输出是:

smithern, harry smithhern, anne

^ 指定字段或记录的开头。命令行:
awk '$2 ~ /^h/' testfile

将把字符 h 作为第二个字段的第一个字符的所有记录打印至标准输出。此示例中的输出是:

smithern, harry

$ 指定字段或记录的末尾。命令行:
awk '$2 ~ /y$/' testfile

将把字符 y 作为第二个字段的最后一个字符的所有记录打印至标准输出。此示例中的输出是:

smawley, andy smithern, harry

. (句号) 表示除了在空白末尾的终端换行字符以外的任何一个字符。命令行:
awk '/a..e/' testfile

将具有以两个字符隔开的字符 a 和 e 的所有记录打印至标准输出。此示例中的输出是:

smawley, andy smiley, allen smithhern, anne

*(星号) 表示零个或更多的任意字符。命令行:
awk '/a.*e/' testfile

将具有以零个或更多字符隔开的字符 a 和 e 的所有记录打印至标准输出。此示例中的输出是:

smawley, andy smiley, allen smithhern, anne smitters, alexis

\ (反斜杠) 转义字符。当位于在扩展正则表达式中具有特殊含义的任何字符之前时,转义字符除去该字符的任何特殊含义。例如,命令行:
/a\/\//

将与模式 a // 匹配,因为反斜杠否定斜杠作为正则表达式定界符的通常含义。要将反斜杠本身指定为字符,则使用双反斜杠。有关反斜杠及其使用的更多信息,请参阅以下关于转义序列的内容。

举例:把一个文件里面所有包含 abc 的行里面的 abc 替换成 def,然后输出第一列和第三列


awk '$0 ~ /abc/ {gsub("abc", "def", $0); print $1, $3}' abc.txt

 

posted @ 2021-06-25 11:28  一无是处谢  阅读(152)  评论(0编辑  收藏  举报