2009-03-02

shell, awk, perl的字符串处理

文本处理主要涉及以下几个问题: 1. 求字符串的长度; 2. 查找一字符串在另一字符串中的位置; 3. 用一字符串替换另一字符串; 4. 提取子字符串; 5. 删除子字符串

  1. shell

  2. shell的字符串操作方法很丰富,不过有点乱.
    shell的字符串操作方法主要分为两类: 变量替换(parameter substitution即有${VARIBALE}的方式引用变量)和expr命令
    1. parameter substitution的方式
    1.1 求字符串长度
    ${#string}
    $ string=123abc456

    $ echo ${#string}
    9

    1.2 查找一字符串在另一字符串中的位置--(没有)
    1.3 用一字符串替换另一字符串
    ${string/substring/replacement} 将第一个出现的substring换为replacement
    ${string//substring/replacement} 将所有substring换为replacement
    $ string=123abc456abc

    $ echo ${string/abc/ABC}
    123ABC456abc

    $ echo ${string//abc/ABC}
    123ABC456ABC

    ${string/#substring/replacement} 如果substring出现在字符串开头,则将它换为replacement
    ${string/%substring/replacement} 如果substring出现在字符串结尾,则将它换为replacement
    $ string=123abc456abc123abc

    $ echo ${string/#123/NUMBER}
    NUMBERabc456abc123abc

    $ echo ${string/%abc/ALPHA}
    123abc456abc123ALPHA

    1.4 提取子字符串
    ${string:position} 提取从第position个字符开始到字符串结尾的子串
    ${string:position:length} 提取从第position个字符开始的长度为length的子串
    $ string=123456

    $ echo ${string:2}
    3456

    $ echo ${string:2:3}
    345

    注意字符下标是从0开始的
    1.5 删除子字符串
    ${string#substring} 删除字符串开头的与substring匹配的最短的那个子串
    ${string##substring} 删除字符串开头的与substring匹配的最长的那个子串
    $ string=123abc123abcABC

    $ echo ${string#1*c}
    123abcABC

    $ echo ${string##1*c}
    ABC

    $ echo ${string#a*c}
    123abc123abcABC

    ${string%substring} 删除字符串尾部的与substring匹配的最短的那个子串
    ${string%%substring} 删除字符串尾部的与substring匹配的最长的那个子串
    $ echo ${string%a*C}
    123abc123

    $ echo ${string%%a*C}
    123

    可见,parameter substitution的格式主要是在string后面附上一个操作符,/是替换,#和%是删除, :是提取子串
    其中替换和删除在操作符后面还可加一个标识.
    使用#的都是对字符串开头的子串操作(替换,删除);使用%的都是对字符串末尾的子串操作(替换,删除)
    2. expr命令的方式
    2.1 求字符串的长度
    expr length $string
    expr "$string" : '.*'
    $ echo `expr length $string`
    15

    $ echo `expr "$string" : '.*'`
    15

    上面第二种方法其实是用到了求最长子串长度的方法,这是parameter subsitution所没有的功能
    expr match "$string" '$substring'

    expr "$string" : '$substring'
    其中的$substring是一正则表达式
    $ echo $string
    123abc123abcABC

    $ echo `expr match "$string" '123[a-c]*'`
    6

    $ echo `expr "$string" : '123[a-c]*'`
    6

    2.2 查找一字符在另一字符串中的位置
    expr index $string $substring
    注意这里查找的是字符,不是字符串
    $ echo $string
    123abc123abcABC

    $ echo `expr index $string 'ca'`
    4

    上面查找的是c或a在string中第一次出现的位置
    2.3 用一字符串替换另一字符串--(没有)
    2.4 提取子字符串
    expr substr $string $position $length
    $ string=123456

    $ expr substr $string 3 3
    345
    注意字符下标是从1开始的
    expr match "$string" '\($substring\)'
    expr "$string" : '\($substring\)'
    $ string=123abc
    $ echo `expr match $string '\(123[a-z]*\)'`
    123abc
    $ echo `expr match $string '123\([a-z]*\)'`
    abc
    expr提取字符串的语法和求最长子串长度的语法区别在于括号,要特别注意区分
    2.5 删除字符串--用替换功能实现,把替代物设为空即可
  3. awk

  4. awk相对于shell来说就简洁得多了,它统一使用函数来进行操作,没有shell那么多纷繁复杂的方式.
    1. 求字符串的长度
    length(string)
    $ awk '{ print length ( $1 ) }' -
    hello
    5
    for note
    3

    2. 查找一字符串在另一字符串中的位置;
    index(string, substring)
    $ awk '{ print index ( $1, $2 ) }' -
    hello ll
    3
    fornote rn
    3

    3. 用一字符串替换另一字符串
    sub(regexp,replacement,string)
    gsub(regexp,replacement,string)
    第一个相当于shell的 ${string/substring/replacement} 不过sub的substring是一正则表达式
    第二个相当于shell的 ${string//substring/replacement} 不过gsub的substring是一正则表达式
    还有一点不同的是,shell不会修改string,而sub和gsub会修改string
    $ cat awk.test
    {
    string="abc123"
    sub(/[0-9]/, "NUMBER", string);
    print string;
    gsub(/[0-9]/, "NUMBER", string);
    print string;
    }

    $ awk -f awk.test awk.test
    abcNUMBER23
    abcNUMBERNUMBERNUMBER
    abcNUMBER23
    abcNUMBERNUMBERNUMBER
    abcNUMBER23
    abcNUMBERNUMBERNUMBER
    abcNUMBER23
    abcNUMBERNUMBERNUMBER
    abcNUMBER23
    abcNUMBERNUMBERNUMBER
    abcNUMBER23
    abcNUMBERNUMBERNUMBER
    abcNUMBER23
    abcNUMBERNUMBERNUMBER

    4. 提取子字符串
    substr(string,position,len)
    $ awk '{ print substr( $1, 3, 4 ) }' -
    helloworld
    llow
    123456
    3456

    注意字符下标是从1开始的
    5. 删除子字符串 -- 用sub或gsub实现即可,只要把替换物设为空
  5. perl

  6. 1. 求字符串的长度
    和awk一样,也是用length函数
    $ perl
    $string="123456";
    print length($string);
    6
    2. 查找一字符串在另一字符串中的位置
    和awk一样,使用index
    $ perl
    $str="hello world";
    print index $str, "or";
    7

    3. 用一字符串替换另一字符串
    perl的这个功能和shell,awk都不同. 它是用s/REGEXP/REPLACEMENT/来实现的
    $ perl
    $string="123abc";
    $string =~ s/[0-9]/NUMBER/g;
    print $string;
    NUMBERNUMBERNUMBERabc

    可以看到,在s///后面也可以加sed的s命令的各种FLAG.
    4. 提取子字符串
    和awk一样,也是用substr(string,position,len)
    $ perl
    $string="123456";
    print substr($string, 3, 4);
    456

    注意awk的字符串的第一个字符的positin是1,而perl的字符串的第一个字符的position是0
    5. 删除子字符串 -- 用字符串替换的功能实现,把替换物设为空即可




转载请注明出处 http://fornote.blogspot.com/

没有评论:

发表评论