linux常用命令学习之awk命令

来源:互联网 发布:淘宝秒刷销量一天千单 编辑:程序博客网 时间:2024/05/01 04:02

百度百科:

        AWK是一种优良的文本处理工具。它不仅是 Linux 中也是任何环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母)的最大功能取决于一个人所拥有的知识。AWK 提供了极其强大的功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上 AWK 的确拥有自己的语言:AWK 程序设计语言, 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

  最简单地说, AWK 是一种用于处理文本的编程语言工具。AWK 在很多方面类似于 shell 编程语言,尽管 AWK 具有完全属于其本身的语法。它的设计思想来源于 SNOBOL4 、sed 、Marc Rochkind设计的有效性语言、语言工具 yacc 和 lex ,当然还从 C 语言中获取了一些优秀的思想。在最初创造 AWK 时,其目的是用于文本处理,并且这种语言的基础是,只要在输入数据中有模式匹配,就执行一系列指令。该实用工具扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。

命令格式: awk [options] 'script' var=value file(s)     

                     awk [options] -f scriptfile var=value file(s)


options命令选项

-F fs or --field-separator fs

指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:

-v var=value or --asign var=value

赋值一个用户定义变量

-f scripfile or --file scriptfile

从脚本文件中读取awk命令。

-mf nnn and -mr nnn

对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。

-W compact or --compat, -W traditional or --traditional

在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。

-W copyleft or --copyleft, -W copyright or --copyright

打印简短的版权信息。

-W help or --help, -W usage or --usage

打印全部awk选项和每个选项的简短说明。

-W lint or --lint

打印不能向传统unix平台移植的结构的警告。

-W lint-old or --lint-old

打印关于不能向传统unix平台移植的结构的警告。

-W posix

打开兼容模式。但有以下限制,不识别:\x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符**和**=不能代替^和^=;fflush无效。

-W re-interval or --re-inerval

允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。

-W source program-text or --source program-text

使用program-text作为源代码,可与-f命令混用。

-W version or --version

打印bug报告信息的版本。


模式和操作

awk脚本是由模式和操作组成的:

pattern {action} 如$ awk '/root/' test,或$ awk '$3 < 100' test

两者是可选的,如果没有模式,则action应用到全部记录,如果没有action,则输出匹配全部记录。默认情况下,每一个输入行都是一条记录,但用户可通过RS变量指定不同的分隔符进行分隔。

模式

模式可以是以下任意一个:

    /正则表达式/:使用通配符的扩展集。

    关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。

    模式匹配表达式:用运算符~(匹配)和~!(不匹配)。

    模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。

    BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。

    END:让用户在最后一条输入记录被读取之后发生的动作。

操作

操作由一人或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内。主要有四部份:

    变量或数组赋值

    输出命令

    内置函数

    控制流命令


环境变量

ARGC    命令行变元个数
ARGV    命令行变元数组
FILENAME   当前输入文件名
FNR      当前文件中的记录号
FS   输入域分隔符,默认为一个空格
RS   输入记录分隔符
NF   当前记录里域个数
NR   到目前为止记录数
OFS   输出域分隔符
ORS   输出记录分隔符


运算符

= += -= *= /= %= ^= **=    赋值
?:    C条件表达式
||     逻辑或
&&     逻辑与
~ ~!    匹配正则表达式和不匹配正则表达式
< <= > >= != ==    关系运算符
空格    连接
+ -        加,减
* / &     乘,除与求余
+ - !     一元加,减和逻辑非
^ ***    求幂
++ --    增加或减少,作为前缀或后缀
$          字段引用
in         数组成员


例子

范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现,则匹配到开头或末尾。如$ awk '/root/,/mysql/' test将显示root第一次出现到mysql第一次出现之间的所有行。

awk '/101/'  file

显示file中包含101的匹配行

awk '/101/,/105/'  file

显示file中在101和105之间的内容

awk '$1 == 5'  file

匹配file中第一列是5的所有行

awk '$1 == "CT"' file

匹配file中第一个列域是CT的所有行

awk -F "|" '{print $1}'   file

按照新的分隔符“|”作为列域分隔符对file进行操作

awk '$2 >5 && $2<=15'     file

匹配file中第二列大于5并且小于15的所有行

awk '{print NR,NF,$1,$NF,}' file

显示文件file的当前记录号、域数和每一行的第一个和最后一个域

awk '/101/ {print $1 $2}' file

显示文件file的匹配行的第一、二个域,但显示时域中间没有分隔符

df | awk '$4>1000000 '

通过管道符|获得输入,如:显示第4个列域大于1000000的行

awk -f awkfile file

对file中的所有行依次执行awkfile中的命令

awk '$1 ~ /101/ {print $1}' file

显示文件中第一个域匹配101的所有行

awk   'BEGIN { OFS="%"} {print $1,$2}' file

通过设置输出分隔符(OFS="%")修改输出格式,打印每一行的前两个列域


awk编程

awk   'BEGIN { max=100 ;print "max=" max}   {max=($1 >max ?$1:max); print $1,"Now max is "max}'  file

BEGIN 表示在处理任意行之前进行的操作,取得文件第一个列域的最大值

awk '{$1 == 'Chi' {$3 = 'China'; print}' file

找到匹配行后先将第3个域替换后再显示该行(记录)

awk '{$7 %= 3; print $7}'  file

将第7域被3除,并将余数赋给第7域再打印

awk '/tom/ {count++;} 
         END {print "tom was found "count" times"}' file

END表示在所有输入行处理完后进行处理

awk 'gsub(/\$/,"");gsub(/,/,""); cost+=$4;
         END {print "The total is $" cost>"filename"}'    file

gsub函数用空串替换$和,再将结果输出到filename中


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完成条件语句

    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在某条件时跳过该行,对下一行执行操作


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_的用户名


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}
        }
}
}'


在awk中调用系统变量必须用单引号,如果是双引号,则表示字符串
Flag=abcd
awk '{print '$Flag'}'   结果为abcd
awk '{print  "$Flag"}'   结果为$Flag


参考文档:http://www.linux.gov.cn/shell/awk.htm   

                  http://www.cnblogs.com/repository/archive/2011/05/13/2045927.html



原创粉丝点击