zoukankan      html  css  js  c++  java
  • AWK

    awk提供了许多强大的字符串函数,见下表:
    awk内置字符串函数
    gsub(r,s)    在整个$0中用s替代r
    gsub(r,s,t)    在整个t中用s替代r
    index(s,t)    返回s中字符串t的第一位置
    length(s)    返回s长度
    match(s,r)    测试s是否包含匹配r的字符串
    split(s,a,fs)    在fs上将s分成序列a
    sprint(fmt,exp)    返回经fmt格式化后的exp
    sub(r,s)    用$0中最左边最长的子串代替s
    substr(s,p)    返回字符串s中从p开始的后缀部分
    substr(s,p,n)    返回字符串s中从p开始长度为n的后缀部分 详细说明一下各个函数的使用方法。

    gsub函数有点类似于sed查找和替换。它允许替换一个字符串或字符为另一个字符串或字符,并以正则表达式的形式执行。第一个函数作用于记录$0,第二 个gsub函数允许指定目标,然而,如果未指定目标,缺省为$0。
    index(s,t)函数返回目标字符串s中查询字符串t的首位置。length函数返回字符串s字符长度。match函数测试字符串s是否包含一个正则表达式r定义的匹配。split使用域分隔符fs将字符串s划分为指定序列a。sprint函数类似于printf函数(以后涉及),返回基本输出格式fmt的结果字符串exp。sub(r,s)函数将用s替代$0中最左边最长的子串,该子串被(r)匹配。sub(s,p)返回字符串s在位置p后的后缀。substr(s,p,n)同上,并指定子串长度为n。
    现在看一看awk中这些字符串函数的功能。

    1.gsub
    要在整个记录中替换一个字符串为另一个,使用正则表达式格式,/目标模式/,替换模式/。例如改变学生序号4842到4899:

    $ awk 'gsub(/4842/, “4899”) {print $0}' grade.txt
    J.Troll 07/99 4899 Brown-3 12 26 26

    echo "i am hifdafafdst"|awk '{gsub(/am/,"abcc",$0);print $0}'
    i abcc hifdafafdst

    2.index
    查询字符串s中t出现的第一位置。必须用双引号将字符串括起来。例如返回目标字符串Bunny中ny出现的第一位置,即字符个数。

    $ awk 'BEGIN {print index("Bunny", "ny")} grade.txt
    4

    3.length
    返回所需字符串长度,例如检验字符串J.Troll返回名字及其长度,即人名构成的字符个数。

    $ awk '$1=="J.Troll" {print length($1) " "$1}' grade.txt
    7 J.Troll

    还有一种方法,这里字符串加双引号。

    $ awk 'BEGIN {print length("A FEW GOOD MEN")}'
    14

    4.match
    match测试目标字符串是否包含查找字符的一部分。可以对查找部分使用正则表达式,返回值为成功出现的字符排列数。如果未找到,返回0,第一个例子在ANCD中查找d。因其不存在,所以返回0。第二个例子在ANCD中查找D。因其存在,所以返回ANCD中D出现的首位置字符数。第三个例子在学生J.Lulu中查找u。

    $ awk '{BEGIN {print match("ANCD", /d/)}'
    0
    $ awk '{BEGIN {print match("ANCD", /C/)}'
    3
    $ awk '$1=="J.Lulu" {print match($1, "u")} grade.txt
    4

    5.split
    使用split返回字符串数组元素个数。工作方式如下:如果有一字符串,包含一指定分隔符-,例如AD2-KP9-JU2-LP-1,将之划分成一个数组。使用split,指定分隔符及数组名。此例中,命令格式为("AD2-KP9-JU2-LP-1",parts_array,"-"),split然后返回数组下标数,这里结果为4。还有一个例子使用不同的分隔符。

    $ awk '{BEGIN {print split("123#456#678", myarray, "#")}'
    3

    这个例子中,split返回数组myarray的下标数。数组myarray取值如下:

    Myarray[1]="123"
    Myarray[2]="456"
    Myarray[3]="789"

    6.sub
    使用sub发现并替换模式的第一次出现位置。字符串STR包含‘popedpopopill’,执行下列sub命令sub(/op/,"op",STR)。模式op第一次出现时,进行替换操作,返回结果如下:
    ‘pOPedpopepill’。
    假如grade.txt文件中,学生J.Troll的记录有两个值一样,“目前级别分”与“最高级别分”。只改变第一个为29,第二个仍为24不动,操作命令为sub(/26/,"29",$0),只替换第一个出现24的位置。

    $ awk '$1=="J.Troll" sub(/26/, "29", $0)' grade.txt
    L.Troll 07/99 4842 Brown-3 12 29 26
    L.Transley 05/99 4712 Brown-2 12 30 28

    7.substr
    substr是一个很有用的函数。它按照起始位置及长度返回字符串的一部分。例子如下:

    $ awk '$1=="L.Transley" {print substr($1, 1,5)}' grade.txt
    L.Tan
    上面例子中,指定在域1的第一个字符开始,返回其前面5个字符。
    如果给定长度值远大于字符串长度, awk将从起始位置返回所有字符,要抽取L.Tansley的姓,只需从第3个字符开始返回长度为7。可以输入长度99,awk返回结果相同。

    $ awk '{$1=="L.Transley" {print substr($1, 3,99)}' grade.txt
    Transley

    substr的另一种形式是返回字符串后缀或指定位置后面字符。这里需要给出指定字符串及其返回字串的起始位置。例如,从文本文件中抽取姓氏,需操作域 1,并从第三个字符开始:

    $ awk '{print substr($1, 3)}' grade.txt
    Troll
    Transley

    还有一个例子,在BEGIN部分定义字符串,在END部分返回从第t个字符开始抽取的子串。

    $ awk '{BEGIN STR="A FEW GOOD MEN"} END {print substr(STR,7)) grade.txt
    GOOD MEN

    8.从shell中向awk传入字符串 
    awk脚本大多只有一行,其中很少是字符串表示的,这一点通过将变量传入awk命令行会变得很容易。现就其基本原理讲述一些例子。
    使用管道将字符串stand-by传入awk,返回其长度。

    $ echo "Stand-by" | awk '{print length($0)}'
    8

    设置文件名为一变量,管道输出到awk,返回不带扩展名的文件名。

    $ STR="mydoc.txt"
    $ echo $STR | awk '{print subst($STR, 1, 5)}'
    mydoc

    设置文件名为一变量,管道输出到awk,只返回其扩展名。
    $ STR="mydoc.txt"
    $ echo $STR | awk '{print substr($STR, 7)}'
    txt

    1.print函数  
    例子1:  
    $ date  
    2005年04月30日 星期六 19时29分25秒 CST  
    $ date|awk '{print "Date:" $1 " Time:" $3}'  
    Date:2005年04月30日  
    Time:19时34分24秒  
    注意,用date命令查看时间格式。不同的语言可能格式也不一样,因此 awk也要随之而变 是转义序列,表示换行符。常见转义序列如下表:  转义序列用一个反斜杠后跟一个字母或者数字表示
    转义序列
    含义
    
    退格
    f
    换页

    换行

    制表符(空格)

    回车
    例子2:  
    $ awk '/Sally/{print " Have a nice day, "$1,$2 "!"}' employees  
    Have a nice day, Sally Chang!  
    解释:如果包含模式Sally,则print函数打印两个跳格,串Have a nice day,第一个字段和第二个字段,然后跟叹号。  
    2.  在一个文件里的awk命令  
    如果awk命令放在文件里,就使用-f选项和awk文件名结合使用。处理过程: 把一条记录读到awk的缓存里而且对该记录测试并执行awk文件里的每个命令。在awk完成对第一记录的操作后,删除该记录并把下一条记录读入缓存,依此类推。如果操作不受模式控制,则默认行为是打印整个记录。  
    例子:  
    $ cat employees  
    Tom Jones 4424 5/12/66 543354  
    Mary Adams 5346 11/4/63 28765  
    Sally Chang 1654 7/22/54 650000  
    Billy Black 1683 9/23/44 336500  
    $ cat awkfile  
    /^Mary/{print "Hello Mary!"}  
    {print $1, $2, $3}  
    $ awk -f awkfile employees  
    Tom Jones 4424  
    Hello Mary!  
    Mary Adams 5346  
    Sally Chang 1654  
    Billy Black 1683  
    3. 记录和字段  
    1〉记录:awk不把输入数据看作一个无穷的字符串,而是把它看作一种格式 或结构。默认情况下把每行叫做一个记录(record),并以一个换行符终 止。输入和输出的记录分隔符默是回车符,保存在内置awk变量ORS 和RS中。ORS和RS可以改变,但是方式有限。  
    例子:  
    $ awk '{print $0}' employees  
    Tom Jones 4424 5/12/66 543354  
    Mary Adams 5346 11/4/63 28765  
    Sally Chang 1654 7/22/54 650000  
    Billy Black 1683 9/23/44 336500  
    解释:变量$0保存当前记录,这条命令相当于awk '{print}' employees  
    例子:  
    $ awk '{print NR,$0}' employees  
    1 Tom Jones 4424 5/12/66 543354  
    2 Mary Adams 5346 11/4/63 28765  
    3 Sally Chang 1654 7/22/54 650000  
    4 Billy Black 1683 9/23/44 336500  
    解释:NR代表行号。  
    4字段  
    类似表中的字段,是指记录中的一个词条。默认字段分隔符是空白区字段, 也就是空格或制表符(TAB)。Awk中用NF来记录每条记录的字段数量。  
    字段分隔符  
    输入字段分隔符:awk的内置变量FS保存输入字段分隔符的值。当时用FS 的默认值时,awk用空格或制表符分隔字段,删除前导空白区和制表符。FS 可以改变,可以在BEGIN语句中改变,也可以在命令中改变。要想在命 令中改变需要用-F选项。  
    举例:  
    $ cat employees2  
    Tom Jones:4424:5/12/66:543354  
    Mary Adams:5346:11/4/63:28765  
    Sally Chang:1654:7/22/54:650000  
    Billy Black:1683:9/23/44:336500  
    $ awk '{print $1,$2}' employees2  
    Tom Jones:4424:5/12/66:543354  
    Mary Adams:5346:11/4/63:28765  
    Sally Chang:1654:7/22/54:650000  
    Billy Black:1683:9/23/44:336500  
    $ awk -F: '{print $1,$2}' employees2  
    Tom Jones 4424  
    Mary Adams 5346  
    Sally Chang 1654  
    Billy Black 1683  
    举例2:多个字段分隔符。如果使用多个字段分隔符,要将其封装在方括号里。  
    $ awk -F'[ : ]' '{print $1,$2,$3}' employees2  
    Tom Jones 4424  
    Mary Adams 5346  
    Sally Chang 1654  
    Billy Black 1683  
    解释:把空格、制表符、冒号当成输入字段分隔符。
    输出字段分隔符:默认的输出字段分隔符用逗号来分隔,被分隔的字段之间打 印一个空格,如果字段之间没有逗号,则打印时各字段将挤在一起。  
    5.模式和操作  
    awk 模式(patterns)控制awk将对一行输入作什么样的操作。一个模式包括 一个正则表达式,一个产生正确或者错误条件的表达式,或者它们的组合。 默认操作时打印模式中符合表达式条件的各行。当读入一个模式时,有一条 隐含的if语句。如果if语句是隐含的,周围可以没有花括号。  
    例子:  
    $ awk '$37/22/54 650000  
    Billy Black 1683 9/23/44 336500  
    解释:如果第3个字段小于4000,则打印该字段。  
    操作:操作(actions)是封装在花括号里且由分号分隔的语句。如果一个模式 在一个操作之前,则该模式规定了何时执行该操作。  
    举例:  
    $ awk '/Tom/{print "Hello there," $1}' employees  
    Hello there,Tom  
    解释:如果记录中包含Tom,则打印Hello there,Tom  
    6.正则表达式  
    一个正则表达式对awk来说是一个由封装在正斜杠里的字符组成的模式。Awk 支持的正则表达式与egrep基本一样,可以参考下表
    元字符
    说明
    ^
    字符串首
    $
    字符串尾
    .
    单个任意字符
    *
    零个或者多个前导字符
    +
    一个或者多个前导字符
    ?
    零个或者一个前导字符
    [ABC]
    匹配【】中的任一字符
    [^ABC]
    匹配任何一个不在【】中的字符
    [A-Z]
    匹配A-Z之间的任一字符
    A|B
    A或者B
    (AB)+
    一个或者多个AB组合
    *
    *本身
    &
    替代符,替代查找串中匹配的内容
    举例:  
    $ awk '/^Mary/' employees  
    Mary Adams 5346 11/4/63 28765  
    解释:显示employees文件中以Mary开头的行  
    $ awk '/^[A-Z][a-z]* /' employees  
    Tom Jones 4424 5/12/66 543354  
    Mary Adams 5346 11/4/63 28765  
    Sally Chang 1654 7/22/54 650000  
    Billy Black 1683 9/23/44 336500  
    解释:显示行开头是一个大写字母,然后跟一个或多个小写字母,再跟一个
    空格。  
    匹配操作符(~)、否定号(!)用来与以条记录或字段里的表达式相匹配。  
    例子:  
    $ awk '$1 ~/[Bb]ill/' employees  
    Billy Black 1683 9/23/44 336500  
    解释:awk将显示第一个字段里与Bill或者bill相匹配的行  
    $ awk '$1 !~/ly$/' employees  
    Tom Jones 4424 5/12/66 543354  
    Mary Adams 5346 11/4/63 28765  
    解释:显示第一个字段中末尾不是ly的所有行。  
    比较表达式比较行,如果行里的条件为真,就执行操作。如果给表达式求值 为真则值等于1,反之等于0。  
    7.关系操作符  
    下表列出了关系操作符。  
    运算符
    含义
    示例

    小于
    x
    小于等于
    x
    ==
    等于
    x==y
    !=
    不等于
    x!=y
    >=
    大于等于
    x>=y
    >
    大于
    x>y
    ~
    与正则表达式匹配
    X~/y/
    !~
    不与正则表达式匹配
    x!~/y/
    关系操作符举例:  
    $ cat employees  
    Tom Jones 4423 5/12/66 543354  
    Mary Adams 5346 11/4/63 28765  
    Sally Chang 1654 7/22/54 650000  
    Billy Black 1683 9/23/44 336500  
    $ awk '$3==4423' employees  
    Tom Jones 4423 5/12/66 543354  
    $ awk '$3 >;5000{print $1}' employees  
    Mary  
    $ awk '$2 !~/Adam/' employees  
    Tom Jones 4423 5/12/66 543354  
    Sally Chang 1654 7/22/54 650000  
    Billy Black 1683 9/23/44 336500  
    条件表达式:一个条件表达式用两个符号,问号和冒号来给表达式求值。  
    8.条件表达式  
    格式:  
    conditional expression1?expression2:expression3  它等同于
    {if(expression1)  
    expression2  
    else  
    expression3  
    }  
    条件表达式举例:  
    awk '{max=($1>;$2)?$1:$2;print max}' employees 
    解释:如果第一个字段大于第二个字段,就把第一个字段的内容赋给max,反之把第
    二个字段的内容赋给max,然后打印max  
    9.计算  
    可以在模式里执行计算。awk以浮点方式执行所有的算术运算。
    +  加  
    -  减  
    * 乘  
    / 除  
    10.复合模式  
    复合模式 (compound patterns) 是把模式和逻辑操作符相结合的表达式,给 一个表达式从左到右求值。  
                                  逻辑运算符
    运算符
    含义
    例子
    &&
    逻辑与
    A&&B
    ||
    逻辑或
    A||B
    !
    逻辑非
    !A
    复合模式举例:  
    $ awk '$3>;4000 && $35/12/66 543354  
    Mary Adams 5346 11/4/63 28765  
    $ awk '!($3>;4000 && $311.范围模式  
    范围模式从一个模式的第一次出现匹配到第二个模式的第一次出现,然后从 第一个模式的第二次出现匹配到第二个模式的第二次出现等等。如果第一个 模式被匹配,而第二个模式没有找到,则awk将显示直到末尾的所有行。  
    例子:  
    $ cat datafile  
    northwest NW Joel Craig 3.0 .98 3 4  
    western WE Sharon Kelly 5.3 .97 5 23  
    southwest SW Chris Foster 2.7 .8 2 18  
    southern SO May Chin 5.1 .95 4 15  
    southeast SE Derek Johnson 4.0 .7 4 17  
    eastern EA Susan Beal 4.4 .84 5 20  
    northeast NE TJ Nichols 5.1 .94 3 13  
    north NO Val Shultz 4.5 .89 5 9  
    central CT Sheri Watson 5.7 .94 5 13  
    $ awk '/^north/,/^west/' datafile  
    northwest NW Joel Craig 3.0 .98 3 4  
    western WE Sharon Kelly 5.3 .97 5 23  
    northeast NE TJ Nichols 5.1 .94 3 13  
    north NO Val Shultz 4.5 .89 5 9  
    central CT Sheri Watson 5.7 .94 5 13  
    12.变量  
    内置变量要大写,他们可以用在表达式里而且可以被重置。如下表  
    变量名
    含义
    ARGC
    命令行参数的数目
    FILENAME
    当前输入文件的的文件名
    FNR
    当前文件的记录数
    FS
    输入字段分隔符,默认为空格
    NF
    当前记录中的字段数
    NR
    目前的记录数
    OFS
    输出字段分隔符
    ORS
    输出记录分隔符
    RS
    输入记录分隔符
    IGNORECASE
    在正则表达式和字符串匹配中不区分大小写(值为非0时)
    内置变量举例:  
    $ awk -F: '$1=="Mary Adams"{print NR,$1,$2,$NF}' employees2  
    2 Mary Adams 5346 28765  
    解释:-F选项把分隔符改成冒号。如果字段1等于Mary Adams,则打印记 录号、第一个字段、第二个字段和最后一个字段($NF)  
    赋值运算符
    运算符
    含义
    等效表达式
    =
    A=5
    A=5
    +=
    A=a+5
    A+=5
    -=
    A=a-5
    a-=5
    *=
    A=a*5
    A*=5
    /=
    A=a/5
    a/=5

     

  • 相关阅读:
    通过理解List和IList的区别,加深对接口回调的理解
    mysql学习笔记之mysqlparameter(摘)
    MSSQL表中字段更新后,视图中的字段不更新的解决办法
    如何设置firefox,使其可以支持剪贴板
    CSS图片下载器
    VS2008下.NET 单元测试工具 NUnit2.5 配置与集成方法
    discuz x1.5通过uchome注册后免激活补丁(自动激活)
    (转)七秘诀工作效率与薪水翻番
    TRIGGER OF ORACLE
    SQL LOADER 的使用
  • 原文地址:https://www.cnblogs.com/xieqianli/p/4219557.html
Copyright © 2011-2022 走看看