免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1164 | 回复: 0
打印 上一主题 下一主题

awk 实例 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-06 17:16 |只看该作者 |倒序浏览

               

  Normal
  0
  
  7.8 磅
  0
  2
  
  false
  false
  false
  
   
   
   
   
   
   
   
   
   
   
   
   
  
  MicrosoftInternetExplorer4



/* Style Definitions */
table.MsoNormalTable
        {mso-style-name:普通表格;
        mso-tstyle-rowband-size:0;
        mso-tstyle-colband-size:0;
        mso-style-noshow:yes;
        mso-style-parent:"";
        mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
        mso-para-margin:0cm;
        mso-para-margin-bottom:.0001pt;
        mso-pagination:widow-orphan;
        font-size:10.0pt;
        font-family:"Times New Roman";
        mso-fareast-font-family:"Times New Roman";
        mso-ansi-language:#0400;
        mso-fareast-language:#0400;
        mso-bidi-language:#0400;}
ls -l $*| awk '
BEGIN{ print "BYTES","\t","FILE"}
NF==9 &&/^-/{
sum +=$5
++filenum
print $5,"\t",$9
}
NF==9&&/^d/{
print "","\t",$9
}
END {
print "total:",sum,"bytes (" filenum
"files)"
}
'
这段代码放在一个文件中用来统计该目录下的文件,ls -l是列举当前目录的所有文件信息,通过管道传递给awk,作为输入,从格式可以看出 awk 后面的内容都用单引号括注,每个语句后面没有分号之类的东西。
下面就是 模式+操作 的样式,操作都要用{}括起来,并且{一定要跟在模式后面。
其中模式类似于条件,如果是要正则匹配一般用/^d/这种样式。
NF为awk系统变量,代表每行的字段个数

然后将该文件改为可执行文件,chmod 777 lstest
执行./lstest就可以了

awk '{print $1,$2}' stu 输出文件stu中每行的第一个和第二个字段
awk -F: '{print $1 $2}' /etc/passwd  
-F是重新制定字段分隔符的标志,后面紧跟着的字符就是要采用的分隔符,比较灵活
$10 ~/0/ 用来判断第10个字段是否与0匹配。

下面这个是统计独立用户的例子,注意模式里边的操作,如果还需要判断就用if就可以了。
/INFO/ {
if($10 ~/0/) {
if(mobile[$10]==0)
{
mobile[$10]=1
total++
}

num++
print $10
}
}
END {
print "total phonenumber:" ,total
print "number phonenumber:" ,num
}
http://www.ibm.com/developerworks/cn/linux/shell/awk/awk-1/
Awk 是一种名称奇怪但功能强大的语言。本文是一个包含三部分的系列的第一篇。在本文中,DanielRobbins 将使您迅速掌握 awk 编程技巧。随着本系列的进展,将讨论更高级的主题,最后将演示一个真实的高级 awk 应用程序。
            
捍卫 awk
            
在这一系列的文章中,我将使您成为精通 awk 的编程人员。我承认,awk 并没有一个非常好听且又非常 “时髦” 的名字。awk 的 GNU
版本(叫作 gawk)听起来非常怪异。那些不熟悉这种语言的人可能听说过
"awk",而且可能认为它是一组落伍且过时的混乱代码。它甚至会使最博学的 UNIX 权威陷于混乱的边缘(使他不断地发出 "kill -9!"
命令,就象使用咖啡机一样)。
            
的确,awk 没有一个动听的名字。但它是一种很棒的语言。awk
适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行多种方式的编程。与某些语言不同,awk
的语法较为常见。它借鉴了某些语言的一些精华部分,如 C 语言、python 和 bash(虽然在技术上,awk 比 python 和 bash
早创建)。awk 是一种一旦学会就会成为您战略代码库的重要部分的语言。
            




回页首
第一个 Awk
            

应该会看到 /ect/passwd 文件中的内容,本文使用该文件来解释 awk 的工作原理。当调用 awk 时,我们指定
/etc/passwd 作为输入文件。Awk 在执行期间对 /etc/passwd 文件中的每一行依次执行 print 命令。所有输出都发送到
stdout,可以得到类似 cat 命令的结果。
            
现在解释代码块 { print }。在 Awk 中,花括号用于将代码分块,这与 C 语言类似。我们的代码块中只有一条 print 命令。在 Awk 中,当 print 命令单独出现时,将打印当前行的全部内容。
            $ awk '{ print $0 }' /etc/passwd
            
在 Awk 中,变量 $0 表示整个当前行,因此
print 和 print $0 的作用完全相同。
            $ awk '{ print "" }' /etc/passwd
            $ awk '{ print "hiya" }' /etc/passwd
            
运行该脚本,屏幕上讲显示多行 hiya。:)
            




回页首
多个字段
            print $1
            $ awk -F":" '{ print $1 $3 }' /etc/passwd
            halt7
operator11
root0
shutdown6
sync5
bin1
....etc.
             print $1 $3
            $ awk -F":" '{ print $1 " " $3 }' /etc/passwd
            $1
            $3
            $ awk -F":" '{ print "username: " $1 "\t\tuid:" $3 }' /etc/passwd
            username: halt          uid:7
username: operator      uid:11
username: root          uid:0
username: shutdown      uid:6
username: sync          uid:5
username: bin           uid:1
....etc.
            




回页首
外部脚本
            BEGIN {
        FS=":"
}
{ print $1 }
            
两种方法的区别在于如何设置字段分隔符。在该脚本中,(通过设置 FS 变量)在代码中指定字段分隔符,而前一示例通过在命令行向 awk 传递
-F":" 选项来设置 FS。一般而言,最好在脚本内部设置字段分隔符,因为这样可以少输入一个命令行参数。本文稍后将深入讲解 FS 变量。
            




回页首
BEGIN 与 END 代码块
            
通常,awk 会针对每个输入行执行一次每个代码块。但是,在许多编程情形下,可能需要在 awk 开始处理输入文件的文本之前
执行初始化代码。对这种情况,awk 支持定义 BEGIN 代码块。前一示例使用了这种代码块。因为 BEGIN 代码块在 awk
开始处理输入文件之前执行,因此它是初始化 FS(字段分隔符)变量、打印页眉或者初始化在后续程序中将要引用的其他全局变量的绝佳位置。
            
另外,awk 还提供了另一种称为 END 的专用代码块。在输入文件的所有行处理完毕之后,awk 执行这个代码块。通常,END 代码块用于进行最终计算或者打印应该在输出流结尾处出现的汇总信息。
            




回页首
正则表达式与代码块
            /foo/ { print }
            /[0-9]+\.[0-9]*/ { print }
            




回页首
表达式与代码块
下面这两个都是相当于条件,前面的模式是一种执行条件,后面是操作
            fred
            print
            $1 == "fred" { print $3 }
            root
            $5 ~ /root/ { print $3 }
            




回页首
条件语句
            if
            {
        if ( $5 ~ /root/ ) {
                print $3
        }
}
            
两个脚本的作用相同。第一个示例的布尔表达式位于代码块外,而第二个示例的代码块会针对每个输入行执行一次,本文使用 if 语句有选择地执行打印命令。两种方法都可以使用,可以选择与脚本的其他部分最匹配的方法。
            if
            if
            {
        if ( $1 == "foo" ) {
                if ( $2 == "foo" ) {
                        print "uno"
                } else {
                        print "one"
                }
        } else if ($1 == "bar" ) {
                print "two"
        } else {
                print "three"
        }
}
            if
            ! /matchme/ { print $1 $3 $4 }
            {        
        if ( $0 !~ /matchme/ ) {
                print $1 $3 $4
        }
}
            
两个脚本都会只输出 包含 matchme 字符序列的行。也可以选择最适合您的代码的方法。它们的功能完全相同。
            ( $1 == "foo" ) && ( $2 == "bar" ) { print }
            
该示例只打印第一个字段等于 foo
                第二字段等于 bar 的行。
            




回页首
数值变量!
            
在 BEGIN 代码块中,我们将整型变量 x 初始化为零。这样,awk 每次遇到空白行时都将执行
x=x+1 语句,递增 x 值。在所有行都处理完毕之后,awk 执行 END 代码块,并打印最终的汇总信息,以显示它找到的空白行数。
            




回页首
字符串化变量
            2.01
             1.01
            x
            $( )
            1.01
            { print ($1^2)+1 }
            
稍做试验就可以发现,如果特定变量不包含效数字,那么 awk 在计算数学表达式时将该变量当作数值零处理。
            




回页首
众多运算符
            
Awk 的另一个优点是它拥有全面的数学运算符。除了标准的加减乘除,awk 还支持前面演示的指数运算符 “^”、求模(余数)运算符 “%” 和借鉴自 C 语言的大量方便的赋值运算符。
            
其中包括前后加/减(i++、--foo),
加减乘除赋值运算符(a+=3、b*=2、c/=2.2、d-=6.2)。而且,这仅仅是一部分 —— 我们还能使用方便的求模/指数赋值运算符(a^=2、b%=4)。
            




回页首
字段分隔符
            
Awk
有其自己的特殊变量集合。其中一些变量支持调优 awk 性能,而且可以读取另一些变量来收集关于输入的重要信息。前面已经接触过特殊变量
FS。如前所述,这个变量支持设置 awk 期望在字段中找到的字符序列。当我们使用 /ect/passwd 作为输入时,FS 设为
":"。尽管这样做可以解决问题,但 FS 还支持更高的灵活性。
            FS="\t+"
            
上面使用特殊的正则表达式字符 “+”,表示 “一个或多个前一字符”。
            FS="[[:space:]+]"
            
尽管该赋值运算符能够解决问题,但是并非必要。为什么呢?因为在默认情况下,FS 被设为单个空格字符,awk 将其解释为 “一个或多个空格或制表符”。在这个特定的示例中,默认的 FS 设置恰好是您最想要的设置。
分隔符可以延伸为各种字母组合
            FS="foo[0-9][0-9][0-9]"
            




回页首
字段数目
            {       
        if ( NF > 2 ) {
                print $1 " " $2 ":" $3
        }
}
            




回页首
记录数目
            {
        #skip header
        if ( NR > 10 ) {
                print "ok, now for the real information!"
        }
}
            
Awk 还提供了一些具有多种用途的其他变量。后续文章中将深入讲解这些变量。
            
我们对 awk 的初次探究现在就结束了。随着本系列的延续,我将演示更高级的 awk 功能,我们将用一个真实的 awk 应用程序作为本系列的结尾。同时,如果急于学习更多知识,请参考下面列出的参考资料。
        
参考资料
            
  • 您可以参阅本文在 developerWorks 全球站点上的
    英文原文

  • 如果喜欢优秀的传统书籍,那么 O'Reilly 出版的 sed & awk, 2nd
    Edition 是不错的选择。
  • 查阅 comp.lang.awk
    FAQ。其中还包含许多额外的 awk 链接。
  • Patrick Hartigan 的
    awk 教程
    附带了一些实用的 awk 脚本。

        
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/80919/showart_1777823.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP