代码之家  ›  专栏  ›  技术社区  ›  Naveen Dennis

shell脚本中的%和%有什么区别?

  •  3
  • Naveen Dennis  · 技术社区  · 7 年前

    在bash脚本中,当 t="hello.txt" 二者都

    ${t%%.txt} ${t%.txt} 退货 "hello"

    同样的道理 ${t##*.} ${t#*.} 退货 "txt" .

    他们之间有区别吗?它们是如何工作的?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Benjamin W.    7 年前

    简而言之, %% 尽可能地移除, % 尽可能少。

    # t="hello.world.txt"
    # echo ${t%.*}
    hello.world
    # echo ${t%%.*}
    hello
    

    从bash手册:

    '${PARAMETER%WORD}'
    '${PARAMETER%%WORD}'
         The WORD is expanded to produce a pattern just as in filename
         expansion.  If the pattern matches a trailing portion of the
         expanded value of PARAMETER, then the result of the expansion is
         the value of PARAMETER with the shortest matching pattern (the '%'
         case) or the longest matching pattern (the '%%' case) deleted.  If
         PARAMETER is '@' or '*', the pattern removal operation is applied
         to each positional parameter in turn, and the expansion is the
         resultant list.  If PARAMETER is an array variable subscripted with
         '@' or '*', the pattern removal operation is applied to each member
         of the array in turn, and the expansion is the resultant list.
    
        2
  •  1
  •   Benjamin W.    7 年前

    ${string%substring}
    删除最短匹配项 $substring 从的后面 $string .

    例如:

    # Rename all filenames in $PWD with "TXT" suffix to a "txt" suffix.
    # For example, "file1.TXT" becomes "file1.txt" . . .
    
    SUFF=TXT
    suff=txt
    
    for i in $(ls *.$SUFF)
    do
      mv -f $i ${i%.$SUFF}.$suff
      #  Leave unchanged everything *except* the shortest pattern match
      #+ starting from the right-hand-side of the variable $i . . .
    done ### This could be condensed into a "one-liner" if desired.
    

    ${string%%substring}
    删除最长匹配项 $子字符串 从的后面 $string .

    stringZ=abcABC123ABCabc
    #                    ||     shortest
    #        |------------|     longest
    
    echo ${stringZ%b*c}      # abcABC123ABCa
    # Strip out shortest match between 'b' and 'c', from back of $stringZ.
    
    echo ${stringZ%%b*c}     # a
    # Strip out longest match between 'b' and 'c', from back of $stringZ.