awk 用法:awk ' pattern {action} '
变量名 含义
ARGC 命令行变元个数
ARGV 命令行变元数组
FILENAME 当前输入文件名
FNR 当前文件中的记录号
FS 输入域分隔符,默认为一个空格
RS 输入记录分隔符
NF 当前记录里域个数
NR 到目前为止记录数
OFS 输出域分隔符
ORS 输出记录分隔符
ARGC 命令行变元个数
ARGV 命令行变元数组
FILENAME 当前输入文件名
FNR 当前文件中的记录号
FS 输入域分隔符,默认为一个空格
RS 输入记录分隔符
NF 当前记录里域个数
NR 到目前为止记录数
OFS 输出域分隔符
ORS 输出记录分隔符
1、awk '/101/' file 显示文件file中包含101的匹配行。
awk '/101/,/105/' file
awk '$1 == 5' file
awk '$1 == "CT"' file 注意必须带双引号
awk '$1 * $2 >100 ' file
awk '$2 >5 && $2<=15' file
2、awk '{print NR,NF,$1,$NF,}' file 显示文件file的当前记录号、域数和每一行的第一个和最后一个域。
awk '/101/ {print $1,$2 + 10}' file 显示文件file的匹配行的第一、二个域加10。
awk '/101/ {print $1$2}' file
awk '/101/ {print $1 $2}' file 显示文件file的匹配行的第一、二个域,但显示时域中间没有分隔符。
3、df | awk '$4>1000000 ' 通过管道符获得输入,如:显示第4个域满足条件的行。
4、awk -F "|" '{print $1}' file 按照新的分隔符“|”进行操作。
awk 'BEGIN { FS="[: \t|]" }
{print $1,$2,$3}' file 通过设置输入分隔符(FS="[: \t|]")修改输入分隔符。
awk '/101/,/105/' file
awk '$1 == 5' file
awk '$1 == "CT"' file 注意必须带双引号
awk '$1 * $2 >100 ' file
awk '$2 >5 && $2<=15' file
2、awk '{print NR,NF,$1,$NF,}' file 显示文件file的当前记录号、域数和每一行的第一个和最后一个域。
awk '/101/ {print $1,$2 + 10}' file 显示文件file的匹配行的第一、二个域加10。
awk '/101/ {print $1$2}' file
awk '/101/ {print $1 $2}' file 显示文件file的匹配行的第一、二个域,但显示时域中间没有分隔符。
3、df | awk '$4>1000000 ' 通过管道符获得输入,如:显示第4个域满足条件的行。
4、awk -F "|" '{print $1}' file 按照新的分隔符“|”进行操作。
awk 'BEGIN { FS="[: \t|]" }
{print $1,$2,$3}' file 通过设置输入分隔符(FS="[: \t|]")修改输入分隔符。
Sep="|"
awk -F $Sep '{print $1}' file 按照环境变量Sep的值做为分隔符。
awk -F '[ :\t|]' '{print $1}' file 按照正则表达式的值做为分隔符,这里代表空格、:、TAB、|同时做为分隔符。
awk -F '[][]' '{print $1}' file 按照正则表达式的值做为分隔符,这里代表[、]
5、awk -f awkfile file 通过文件awkfile的内容依次进行控制。
cat awkfile
/101/{print "\047 Hello! \047"} --遇到匹配行以后打印 ' Hello! '.\047代表单引号。
{print $1,$2} --因为没有模式控制,打印每一行的前两个域。
6、awk '$1 ~ /101/ {print $1}' file 显示文件中第一个域匹配101的行(记录)。
7、awk 'BEGIN { OFS="%"}
{print $1,$2}' file 通过设置输出分隔符(OFS="%")修改输出格式。
8、awk 'BEGIN { max=100 ;print "max=" max} BEGIN 表示在处理任意行之前进行的操作。
{max=($1 >max ?$1:max); print $1,"Now max is "max}' file 取得文件第一个域的最大值。
(表达式1?表达式2:表达式3 相当于:
if (表达式1)
表达式2
else
表达式3
awk '{print ($1>4 ? "high "$1: "low "$1)}' file
9、awk '$1 * $2 >100 {print $1}' file 显示文件中第一个域匹配101的行(记录)。
10、awk '{$1 == 'Chi' {$3 = 'China'; print}' file 找到匹配行后先将第3个域替换后再显示该行(记录)。
awk '{$7 %= 3; print $7}' file 将第7域被3除,并将余数赋给第7域再打印。
11、awk '/tom/ {wage=$2+$3; printf wage}' file 找到匹配行后为变量wage赋值并打印该变量。
12、awk '/tom/ {count++;}
END {print "tom was found "count" times"}' file END表示在所有输入行处理完后进行处理。
13、awk 'gsub(/\$/,"");gsub(/,/,""); cost+=$4;
END {print "The total is $" cost>"filename"}' file gsub函数用空串替换$和,再将结果输出到filename中。
1 2 3 $1,200.00
1 2 3 $2,300.00
1 2 3 $4,000.00
awk -F $Sep '{print $1}' file 按照环境变量Sep的值做为分隔符。
awk -F '[ :\t|]' '{print $1}' file 按照正则表达式的值做为分隔符,这里代表空格、:、TAB、|同时做为分隔符。
awk -F '[][]' '{print $1}' file 按照正则表达式的值做为分隔符,这里代表[、]
5、awk -f awkfile file 通过文件awkfile的内容依次进行控制。
cat awkfile
/101/{print "\047 Hello! \047"} --遇到匹配行以后打印 ' Hello! '.\047代表单引号。
{print $1,$2} --因为没有模式控制,打印每一行的前两个域。
6、awk '$1 ~ /101/ {print $1}' file 显示文件中第一个域匹配101的行(记录)。
7、awk 'BEGIN { OFS="%"}
{print $1,$2}' file 通过设置输出分隔符(OFS="%")修改输出格式。
8、awk 'BEGIN { max=100 ;print "max=" max} BEGIN 表示在处理任意行之前进行的操作。
{max=($1 >max ?$1:max); print $1,"Now max is "max}' file 取得文件第一个域的最大值。
(表达式1?表达式2:表达式3 相当于:
if (表达式1)
表达式2
else
表达式3
awk '{print ($1>4 ? "high "$1: "low "$1)}' file
9、awk '$1 * $2 >100 {print $1}' file 显示文件中第一个域匹配101的行(记录)。
10、awk '{$1 == 'Chi' {$3 = 'China'; print}' file 找到匹配行后先将第3个域替换后再显示该行(记录)。
awk '{$7 %= 3; print $7}' file 将第7域被3除,并将余数赋给第7域再打印。
11、awk '/tom/ {wage=$2+$3; printf wage}' file 找到匹配行后为变量wage赋值并打印该变量。
12、awk '/tom/ {count++;}
END {print "tom was found "count" times"}' file END表示在所有输入行处理完后进行处理。
13、awk 'gsub(/\$/,"");gsub(/,/,""); cost+=$4;
END {print "The total is $" cost>"filename"}' file gsub函数用空串替换$和,再将结果输出到filename中。
1 2 3 $1,200.00
1 2 3 $2,300.00
1 2 3 $4,000.00
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>1000&&$4<2000) c1+=$4;
else if ($4>2000&&$4<3000) c2+=$4;
else if ($4>3000&&$4<4000) c3+=$4;
else c4+=$4; }
END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file
通过if和else if完成条件语句
if ($4>1000&&$4<2000) c1+=$4;
else if ($4>2000&&$4<3000) c2+=$4;
else if ($4>3000&&$4<4000) c3+=$4;
else c4+=$4; }
END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file
通过if和else if完成条件语句
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000&&$4<4000) exit;
else c4+=$4; }
END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file
通过exit在某条件时退出,但是仍执行END操作。
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000) next;
else c4+=$4; }
END {printf "c4=[%d]\n",c4}"' file
通过next在某条件时跳过该行,对下一行执行操作。
if ($4>3000&&$4<4000) exit;
else c4+=$4; }
END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file
通过exit在某条件时退出,但是仍执行END操作。
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000) next;
else c4+=$4; }
END {printf "c4=[%d]\n",c4}"' file
通过next在某条件时跳过该行,对下一行执行操作。
14、awk '{ print FILENAME,$0 }' file1 file2 file3>fileall 把file1、file2、file3的文件内容全部写到fileall中,格式为
打印文件并前置文件名。
15、awk ' $1!=previous { close(previous); previous=$1 }
{print substr($0,index($0," ") +1)>$1}' fileall 把合并后的文件重新分拆为3个文件。并与原文件一致。
16、awk 'BEGIN {"date"|getline d; print d}' 通过管道把date的执行结果送给getline,并赋给变量d,然后打印。
17、awk 'BEGIN {system("echo \"Input your name:\\c\""); getline d;print "\nYour name is",d,"\b!\n"}'
通过getline命令交互输入name,并显示出来。
awk 'BEGIN {FS=":"; while(getline< "/etc/passwd" >0) { if($1~"050[0-9]_") print $1}}'
打印/etc/passwd文件中用户名包含050x_的用户名。
18、awk '{ i=1;while(i<NF) {print NF,$i;i++}}' file 通过while语句实现循环。
awk '{ for(i=1;i<NF;i++) {print NF,$i}}' file 通过for语句实现循环。
type file|awk -F "/" '
{ for(i=1;i<NF;i++)
{ if(i==NF-1) { printf "%s",$i }
else { printf "%s/",$i } }}' 显示一个文件的全路径。
用for和if显示日期
awk 'BEGIN {
for(j=1;j<=12;j++)
{ flag=0;
printf "\n%d月份\n",j;
for(i=1;i<=31;i++)
{
if (j==2&&i>28) flag=1;
if ((j==4||j==6||j==9||j==11)&&i>30) flag=1;
if (flag==0) {printf "%02d%02d ",j,i}
}
}
}'
19、在awk中调用系统变量必须用单引号,如果是双引号,则表示字符串
Flag=abcd
awk '{print '$Flag'}' 结果为abcd
awk '{print "$Flag"}' 结果为$Flag
awk '{ for(i=1;i<NF;i++) {print NF,$i}}' file 通过for语句实现循环。
type file|awk -F "/" '
{ for(i=1;i<NF;i++)
{ if(i==NF-1) { printf "%s",$i }
else { printf "%s/",$i } }}' 显示一个文件的全路径。
用for和if显示日期
awk 'BEGIN {
for(j=1;j<=12;j++)
{ flag=0;
printf "\n%d月份\n",j;
for(i=1;i<=31;i++)
{
if (j==2&&i>28) flag=1;
if ((j==4||j==6||j==9||j==11)&&i>30) flag=1;
if (flag==0) {printf "%02d%02d ",j,i}
}
}
}'
19、在awk中调用系统变量必须用单引号,如果是双引号,则表示字符串
Flag=abcd
awk '{print '$Flag'}' 结果为abcd
awk '{print "$Flag"}' 结果为$Flag
____________________________________________________________________________________________________________________________________________________________________________________
(一)
awk最主要的功能是用来分域的.
最常见的用法是
awk '{print $1}' /etc/passwd
下面一句是如果文件的第二个域的值大于1300,则打印文件内所有记录第二个域的值
awk '{if($2>1300) print $2}' /path/to/filename
awk '{if($2>1300) print $2}' /path/to/filename
此句打印文件内所有不包含Yellow或Brown字符的行
awk '$0 !~/(Yellow|Brown)/' /path/to/filename
awk '$0 !~/(Yellow|Brown)/' /path/to/filename
此句打印文件内第一域为Yellow且第四域为Brown字符的行
awk '{if ($1=="Brown" && $4=="Yellow") print $0}' /path/to/filename
awk '{if ($1=="Brown" && $4=="Yellow") print $0}' /path/to/filename
下面一句是用来计算并打印文件所有第一个域的值的总和,和平均值
awk '{sum +=$1} END {print "Sum: ",sum;print "Average:",sum/NR";}' /path/to/filename
awk '{sum +=$1} END {print "Sum: ",sum;print "Average:",sum/NR";}' /path/to/filename
下面一个$NF是比较有用的,NF是记录域的个数,而$NF的含义就成了最后一个域的值了。举出如下一个例子,相信就比较明白了.
lynx -width=300 -dump http://192.168.200.18/server-status|grep "localhost"|awk '{print $11,$14}'|
awk -F/ '{print $NF}'
lynx -width=300 -dump http://192.168.200.18/server-status|grep "localhost"|awk '{print $11,$14}'|
awk -F/ '{print $NF}'
把文件内所有包含Brown字符替换为Yellow。
awk 'gsub(/Brown/,"Yellow") {print $0}' /path/to/filename
awk 'gsub(/Brown/,"Yellow") {print $0}' /path/to/filename
打印文件每一行的长度
awk '{print length($0)}' /path/to/filename
awk '{print length($0)}' /path/to/filename
打印指定字符的长度
awk 'BEGIN {print length("A TO Z")}' /path/to/filename
(二)
a w k能够用很短的程序对文档里的资料做修改、比较、提取、打印等处理。gawk 是G N U计划下所做的a w k,gawk 最初在1 9 8 6年完成,之后不断地被改进、更新。gawk 包含awk 的所有功能。
基本上有两种方法可以执行g a w k程序。
awk 'BEGIN {print length("A TO Z")}' /path/to/filename
(二)
a w k能够用很短的程序对文档里的资料做修改、比较、提取、打印等处理。gawk 是G N U计划下所做的a w k,gawk 最初在1 9 8 6年完成,之后不断地被改进、更新。gawk 包含awk 的所有功能。
基本上有两种方法可以执行g a w k程序。
如果gawk 程序很短,则可以将gawk 直接写在命令行,如下所示:
gawk 'program' input-file1 input-file2 ...
其中program 包括一些pattern 和a c t i o n。
gawk 'program' input-file1 input-file2 ...
其中program 包括一些pattern 和a c t i o n。
如果gawk 程序较长,较为方便的做法是将gawk 程序存在一个文件中,
gawk 的格式如下所示:
gawk -f program-file input-file1 input-file2 ...
gawk 程序的文件不止一个时,执行gawk 的格式如下所示:
gawk -f program-file1 -f program-file2 ... input-file1 input-file2 ...
gawk 的格式如下所示:
gawk -f program-file input-file1 input-file2 ...
gawk 程序的文件不止一个时,执行gawk 的格式如下所示:
gawk -f program-file1 -f program-file2 ... input-file1 input-file2 ...
注意:g a w k只能处理文本文件(A S C I I码文件)。
在g a w k语言中每一个命令都由两部分组成:一个模式( p a t t e r n)和一个相应的动作(a c t i o n)。只要模式符合,g a w k就会执行相应的动作。其中模式部分用两个斜杠括起来,而动作部分用一对花括号括起来。例如:
/ p a t t e r n 1 / { a c t i o n 1 }
/ p a t t e r n 2 / { a c t i o n 2 }
/ p a t t e r n 3 / { a c t i o n 3 }
/ p a t t e r n 1 / { a c t i o n 1 }
/ p a t t e r n 2 / { a c t i o n 2 }
/ p a t t e r n 3 / { a c t i o n 3 }
Actions是由许多awk指令所构成,而awk的指令与c语言中的指令非常类似。
IO指令:print 、 printf( ) 、getline ......
流程控制指令 : if ( ...) {...} else {…}、 while(…){…} ……
例如:
gawk '/scandal/{print $1} /rumor/{print $2}' gossip_file
此命令搜索文件g o s s i p _ f i l e中包括s c a n d a l的记录,并打印第一个字段。然后再从头搜索
g o s s i p _ f i l e中包括r u m o r的记录,并打印第二个字段。
g a w k中有各种的内部函数,部分介绍如下:
system(command) 此函数允许用户执行操作系统的指令,执行完毕后将回到g a w k程序。
例如:BEGIN {system("ls")}
字符串就是一连串的字符,它可以被g a w k逐字地翻译。字符串用双引号括起来。数字不能
用双引号括起来,并且g a w k将它当作一个数值。例如:
gawk '$1 != "Tim" {print}' testfile
此命令将显示第一个字段和Ti m不相同的所有记录。如果命令中Ti m两边不用双引号,g a w k将不能正确执行。再如:
gawk '$1 == "50" {print}' testfile
此命令将显示所有第一个字段和5 0这个字符串相同的记录。g a w k不管第一字段中的数值
的大小,而只是逐字地比较。这时,字符串5 0和数值5 0并不相等。
在g a w k程序中,你可以省略模式和动作两边的引号,因为在g a w k程序中,模式和动作从哪开始和从哪结束时是很显然的。
BEGIN和END: 有两个特殊的模式在g a w k中非常有用。B E G I N模式用来指明g a w k开始处理一个文件之前执行一些动作。B E G I N经常用来初始化数值,设置参数等。E N D模式用来在文件处理完成后执行一些指令,一般用作总结或注释。BEGIN 和E N D中所有要执行的指令都应该用花括号括起来。BEGIN 和E N D必须使用大写。请看下面的例子:
BEGIN { print "Starting the process the file" }
$1 == "UNIX" {print}
$2 > 10 {printf "This line has a value of %d",$ 2 }
END { print "Finished processing the file. Bye!"}
BEGIN { print "Starting the process the file" }
$1 == "UNIX" {print}
$2 > 10 {printf "This line has a value of %d",$ 2 }
END { print "Finished processing the file. Bye!"}
next 和exit: next 指令用来告诉gawk 处理文件中的下一个记录, 而不管现在正在做什么。语法如下:
{ command1
c o m m a n d 2
c o m m a n d 3
n e x t
c o m m a n d 4
}
程序只要执行到n e x t指令,就跳到下一个记录从头执行命令。因此,本例中, c o m m a n d 4
指令永远不会被执行。程序遇到e x i t指令后,就转到程序的末尾去执行E N D,如果有E N D的话。
{ command1
c o m m a n d 2
c o m m a n d 3
n e x t
c o m m a n d 4
}
程序只要执行到n e x t指令,就跳到下一个记录从头执行命令。因此,本例中, c o m m a n d 4
指令永远不会被执行。程序遇到e x i t指令后,就转到程序的末尾去执行E N D,如果有E N D的话。
g a w k语言支持数组结构。数组不必事先初始化。声明一个数组的方法如下:
a r r a y n a m e [ n u m ] = v a l u e
请看下面的例子:
# reverse lines in a file
{line[NR] = $0 } # remember each line
END {var=NR # output lines in reverse order
while (var > 0){
print line[var]
v a r - - }
}
**********************************************************************************************************************************************************************************
a:awk内置变量
a r r a y n a m e [ n u m ] = v a l u e
请看下面的例子:
# reverse lines in a file
{line[NR] = $0 } # remember each line
END {var=NR # output lines in reverse order
while (var > 0){
print line[var]
v a r - - }
}
**********************************************************************************************************************************************************************************
a:awk内置变量
变量名 含义
ARGC 命令行参数个数
ARGV 命令行参数数组
FILENAME string=当前输入的文件名
FNR 在当前文件中当前记录数(对输入文件起始为1)
FS 输入字段分隔符
NF 当前记录的字段数
NR 当前记录数(为全部输入文件)
OFMT 数值的输出格式(默认为%.6g)
OFS 输出字段的分隔符(默认为空格)
ORS 输出记录分隔符(默认为换行符)
RS 输入记录分隔符(默认为换行符)
ARGV 命令行参数数组
FILENAME string=当前输入的文件名
FNR 在当前文件中当前记录数(对输入文件起始为1)
FS 输入字段分隔符
NF 当前记录的字段数
NR 当前记录数(为全部输入文件)
OFMT 数值的输出格式(默认为%.6g)
OFS 输出字段的分隔符(默认为空格)
ORS 输出记录分隔符(默认为换行符)
RS 输入记录分隔符(默认为换行符)
awk允许的测试:
b:操作符 含义
x==y x等于y?
x!=y x不等于y?
x>y x大于y?
x>=y x大于或等于y?
x<y x小于y?
x<=y x小于或等于y?
x~re x匹配正则表达式re?
x!~re x不匹配正则表达式re?
x!=y x不等于y?
x>y x大于y?
x>=y x大于或等于y?
x<y x小于y?
x<=y x小于或等于y?
x~re x匹配正则表达式re?
x!~re x不匹配正则表达式re?
awk的操作符(按优先级升序排列)
= 、+=、 -=、 *= 、/= 、 %=
||
&&
> >= < <= == != ~ !~
xy (字符串连结,'x''y'变成"xy")
+ -
* / %
++ --
||
&&
> >= < <= == != ~ !~
xy (字符串连结,'x''y'变成"xy")
+ -
* / %
++ --
c:awk的函数
int(x) 对x取整
rand 取 0到1之间的随机数
srand(x) 设置x为rand的新输入值
cos(x) 给出x的余弦值
sin(x) 给出x的正弦值
atan2(x,y) 给出y/x的正切值
exp(x) 给出e的x次幂
log(x) 给出x的常用对数值(基为e)
sqrt(x) 给出x的正平方根值
exit(x) 结束awk程序,若有x值,则返回x,否则返回0.
index(s,t) 返回t在s中的第一个开始位置,如t不是s的子串,则返回0]
length(x) 求x的长度(字符个数)
substr(s,x,y) 在字符串s中取得从x个字符开始的长度为y的子字符串.
rand 取 0到1之间的随机数
srand(x) 设置x为rand的新输入值
cos(x) 给出x的余弦值
sin(x) 给出x的正弦值
atan2(x,y) 给出y/x的正切值
exp(x) 给出e的x次幂
log(x) 给出x的常用对数值(基为e)
sqrt(x) 给出x的正平方根值
exit(x) 结束awk程序,若有x值,则返回x,否则返回0.
index(s,t) 返回t在s中的第一个开始位置,如t不是s的子串,则返回0]
length(x) 求x的长度(字符个数)
substr(s,x,y) 在字符串s中取得从x个字符开始的长度为y的子字符串.
AWK提取字符串
echo $str |nawk '{print substr($0,index($0,"[B]")+1,index($0,"[\B]")-index($0,"[B]"))}'
awk中怎么提取字符串中间的不定长子字符串(长度不固定)
awk
[Copy to clipboard] [ - ]CODE:
/home/lee#echo $str|awk '{gsub(/[^0-9]+/,"");print}'
245893519
or,try grep
/home/lee#echo $str|awk '{gsub(/[^0-9]+/,"");print}'
245893519
or,try grep
[Copy to clipboard] [ - ]CODE:
/home/lee#echo $str|grep -o '[0-9]\{1,\}'
245893519
/home/lee#echo $str|grep -o '[0-9]\{1,\}'
245893519
如果是下面的情况:
<B1>+AB2\245893519[/b\]</B>
<B1>+AB2\245893519[/b\]</B>
在unix5.0.5下通过:
nawk 'BEGIN { FS = "]" }
{ for(i = 1; i <= length($2); i++){
if(substr($2, i, 1) == "\[")
break
printf("%s, substr($2, i , 1))}
printf("\n") }' filename
{ for(i = 1; i <= length($2); i++){
if(substr($2, i, 1) == "\[")
break
printf("%s, substr($2, i , 1))}
printf("\n") }' filename