zoukankan      html  css  js  c++  java
  • Learning_the_bash_Shell_Third_Edition 4.2/n(113|95)

    Patterns and Pttern Matching

    We’ll continue refining our solution to Task 4-1 later in this chapter. The next type of string operator is used to match portions of a variable’s string value against patterns. Patterns, as we saw in Chapter 1, are strings that can contain wildcard characters (*, ?, and [] for character sets and ranges). Table 4-2 lists bash’s pattern-matching operators.

    Operator

    Meaning

    ${variable#pattern}

    If the pattern matches the beginning of the variable’s value, delete the shortest part that matches and return the rest.

    ${variable##pattern}

    If the pattern matches the beginning of the variable’s value, delete the longest part that matches and return the rest.

    ${variable%pattern}

    If the pattern matches the end of the variable’s value, delete the shortest part that matches and return the rest.

    ${variable%%pattern}

    If the pattern matches the end of the variable’s value, delete the longest part that matches and return the rest.

    ${variable/pattern/string}

    The longest match to pattern in variable is replaced by string. In the first form, only the first match is replaced. In the second form, all matches are replaced. If the pattern begins with a #, it must match at the start of the variable. If it begins with a%, it must match with the end of the variable. Ifstring is null, the matches are deleted. If variable is@or *, the operation is applied to each positional parameter in turn and the expansion is the resultant list

    ${variable//pattern/string}

    The longest match to pattern in variable is replaced by string. In the first form, only the first match is replaced. In the second form, all matches are replaced. If the pattern begins with a #, it must match at the start of the variable. If it begins with a%, it must match with the end of the variable. Ifstring is null, the matches are deleted. If variable is@or *, the operation is applied to each positional parameter in turn and the expansion is the resultant list

    These can be hard to remember; here’s a handy mnemonic device: # matches the front because number signs precede numbers; % matches the rear because percent signs follow numbers.The classic use for pattern-matching operators is in stripping off components of pathnames, such as directory prefixes and filename suffixes. With that in mind, here is an example that shows how all of the operators work. Assume that the variable path has the value /home/cam/book/long.file.name; then:

    Expression

    Results

    ${path##/*/}

        long.file.name

    ${path#/*/}

       cam/book/long.file.name

    $path           

        /home/cam/book/long.file.name

    ${path%.*}   

        /home/cam/book/long.file

    ${path%%.*}

       /home/cam/book/long

    The two patterns used here are /*/, which matches anything between two slashes,and .*, which matches a dot followed by anything.

    The longest and shortest pattern-matching operators produce the same output unless they are used with the * wildcard operator. As an example, if filename had the value alicece, then both ${filename%ce} and ${filename%%ce} would produce the result alice. This is because ce is an exact match; for a match to occur, the string ce must appear on the end $filename. Both the short and long matches will then match the

    last grouping of ce and delete it. If, however, we had used the * wildcard, then ${filename%ce*} would produce alice because it matches the shortest occurrence of ce followed by anything else. ${filename%%ce*} would return ali because it matches the longest occurrence of ce followed by anything else; in this case the first and second ce.

    kernel_get_var() {
     local token="$1="
     local entry="$(cat /proc/cmdline)"
     local result=""
    
     while echo "${entry}" | grep -q "${token}" ; do
    #If the pattern matches the beginning of the variable’s value, delete the shortest part that matches and return the rest.    entry="${entry#*${token}}"
    #If the pattern matches the end of the variable’s value, delete the longest part that matches and return the rest.    result="${entry%%[ ,]*} ${result}"    entry="${entry#* }"  done  echo "${result}" }

      

     #examples

    ${variable#pattern}

    If the pattern matches the beginning of the variable’s value, delete the shortest part that matches and return the rest.

    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1$ . 1.sh console=
    entry before:aa bb console= ccc ddd eee fff ggg
    entry: ccc ddd eee fff ggg
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1$ . 1.sh ccc
    entry before:aa bb console= ccc ddd eee fff ggg
    entry: ddd eee fff ggg
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1$ cat 1.sh 
    entry="$(cat cline)"
    echo "entry before:${entry}"
    token=$1
    echo  "entry:${entry#*${token}}"
    

      the content of cline is:

    aa bb console= ccc ddd eee fff ggg
    

    when $1 is set to:

    console=
    

      the result is(If the pattern matches the beginning of the variable’s value, delete the shortest part that matches and return the rest.):

            delete the shortest, and return the rest.

    ccc ddd eee fff ggg
    

      

    ${variable%%pattern} 

    If the pattern matches the end of the variable’s value, delete the longest part that matches and return the rest.

    . 1.sh console=
    entry before:aa bb console= ccc ddd eee fff ggg
    entry  after:aa bb console= ccc ddd eee fff ggg
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ cat 1.sh 
    entry="$(cat cline)"
    echo "entry before:${entry}"
    token=$1
    echo  "entry  after:${entry%%*${token}}"
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ cat cline 
    aa bb console= ccc ddd eee fff ggg
    

    #2此时我们的内容是以"console="结尾,所以只会处理结尾的,酱紫看起来 delete的所谓的longest 感觉就没有什么意义了, 奇怪。

    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ cat cline 
    aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkkconsole=
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ . 1.sh console=
    entry before:aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkkconsole=
    entry  after:aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk 

      #longest

    同时通过实验来看, 它只会remove 掉最后一个pattern,更准确的说应该算是截取(cut), cut完最后一个pattern后原样返回剩余的部分

    在echo 截取后的结果的时候再最后面加了一个“&” 来检查实际截取的效果

    #”aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=console=“

    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ cat cline 
    aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=console=
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ . 1.sh console=
    entry before:aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=console=
    entry  after:aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=&
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ cat 1.sh 
    entry="$(cat cline)"
    echo "entry before:${entry}"
    token=$1
    echo  "entry  after:${entry%%${token}}&"
    
      result: "aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console="
     

    #”aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=“

    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ cat cline 
    aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ . 1.sh console=
    entry before:aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=
    entry  after:aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= &
    

      

    result :”aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= “(空格还在)

    #二”aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=console=console=“

    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ cat cline 
    aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=console=console=
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ cat 1.sh 
    entry="$(cat cline)"
    echo "entry before:${entry}"
    token=$1
    echo  "entry  after:${entry%%${token}*}&"
    cornerli@cornerli2:~/chromiumos/factory_install/temp/aug22-1/example-2$ . 1.sh console=
    entry before:aa bb hhhconsole= ccc ddd eee fff ggg iiiii jjjjj kkkkk console= console=console=console=
    entry  after:aa bb hhh&
    

     after: "aa bb hhh&",      看来 ”*“ 的作用真的是超级巨大,匹配到了最靠近左侧的那个

     

     
  • 相关阅读:
    POJ 2342 Anniversary party
    hdu 4339 Query
    Strlcpy和strlcat——一致的、安全的字符串拷贝和串接函数
    C语言直方图 && EOF释疑
    Pig 安装和使用
    时钟、背景音乐、背景图片
    字符串拷贝函数memcpy()、strncpy()和snprintf()性能之比较
    内核编译时提示错误error: sys/types.h: No such file or directory
    ubuntu中liveCD、desktop与alternate版本的区别
    恰恰是实现梦想的可能性,才使生活变得有趣
  • 原文地址:https://www.cnblogs.com/winditsway/p/15175324.html
Copyright © 2011-2022 走看看