【问题标题】:What is the difference between % and %% in shell scripting?shell脚本中的%和%%有什么区别?
【发布时间】:2018-05-22 04:26:54
【问题描述】:

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

${t%%.txt}${t%.txt} 返回 "hello"

${t##*.} 也是如此,${t#*.} 返回 "txt"

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

【问题讨论】:

  • 这些形式的参数扩展通常被称为带子串删除的参数扩展# - 从左边修剪到指定匹配的结尾,包括结尾。 % - 从右侧修剪。 (下面的答案中的详细信息)
  • 请注意,%%% 也用于 printf 内置函数的格式字符串中,并且具有不同且不相关的含义。 (添加以防标题误导某人)

标签: linux bash shell scripting


【解决方案1】:

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

# 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】:

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

    例如:

    # 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 后面删除$substring 的最长匹配项。

    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.
    

    【讨论】:

    • 你可以用反引号包围你的内联代码,并将 ${string%substring} 的格式设置为${string%substring}。非常努力的回答。 (但本杰明也打败了你:)
    猜你喜欢
    • 2011-02-15
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 2017-08-18
    相关资源
    最近更新 更多