bash中特殊字符的角色切换

bash中特殊字符的角色切换

星号的作用凭什么不断变化?

CASE 1: 
var1=abcd-1234-defg 
echo ${var1#*-*}        # RESULT: 1234-defg

CASE 2: 
stringZ=abcABC123ABCabc 
echo `expr match "$stringZ" '\(abc[A-Z]*.2\)'`  # RESULT: abcABC12

星号的作用何时以及如何决定?

CASE 3:
path_name="/home/bozo/ideas/thoughts.for.today"
echo ${path_name##/*/}  # RESULT : thoughts.for.today

在这种情况下,我误认为/在这里扮演了逃避角色的角色,即试图逃避 的基本特征*。好吧,我错了。那么这些特殊角色的角色是如何决定的、由谁决定的呢?

CASE 4: 
var1=abcd--1234-defg 
echo ${var1#*-*}        # RESULT: -1234-defg  & i was expecting 1234-defg

CASE 4 与 CASE 1 类似,但可以看出有所不同abcd--,我也在预料之中1234-defg,但结果却与 CASE 1 相同。

*-*我对案例4的解释是这样的:

shell 会查找从 var1 开头开始的所有内容,直到找到 - OR -- OR ---

为什么我对案例 4 的解释不正确?

答案1

那是因为*在您的测试中具有不同的含义。

情况1,案例3案例4,它用作模式匹配。而在案例2, 它是正则表达式元字符(或量词或克林星)。

在模式匹配中,*字符将匹配任何字符串,包括空字符串,a*将匹配任何以a, example a, aa,开头的字符串ab,但不匹配b

在正则表达式中,*量词匹配零个或多个前面的标记,a*将匹配零个或多个a序列,例如'', a, aa, aaa, ab, b

考虑到这些,您的案例4将被解释为匹配任何包含的字符串-,因为它被用作模式匹配,所以您所讨论的解释被用作正则表达式。

因此abcd--1234-defg,最短的子字符串匹配*-*abcd-,最长的匹配是整个字符串。因为当您使用表单时${var1#*-*},这是一个参数扩展$var1要删除match中的最短前缀*-*,您可以得到-1234-defg,因为匹配的最短前缀是abcd-

答案2

有两点需要理解:

  1. 在一个 glob 中,*匹配零个或多个任何字符的

  2. 该表格${var1#*-*}删除了最短匹配。

因此,${var1#*-*}只会删除第一个破折号,因为这是最短匹配。

为了完整起见,注释${var1##*-*}将删除最长的匹配项。

例子

在下面的每种情况下,最短匹配的前缀被删除:

$ var1=abcd-1234-defg 
$ echo ${var1#*}
abcd-1234-defg
$ echo ${var1#*-}
1234-defg
$ echo ${var1#*-*}
1234-defg
$ echo ${var1#*-*-}
defg
$ echo ${var1#*-*-*}
defg

将上面的情况与##删除的情况进行对比最长匹配前缀:

$ echo ${var1##*-}
defg
$ echo ${var1##*-*}

$ 

文档

man bash

${parameter#word}
${parameter##word}

删除匹配的前缀模式。该单词被扩展以产生一个模式,就像路径名扩展一样。如果模式与参数值的开头匹配,则扩展的结果是扩展后的参数值 最短匹配模式#案例)或最长的匹配模式(##案例)已删除。如果参数是@或*,则依次对每个位置参数应用模式删除操作,并且扩展是结果列表。如果parameter是下标为@或*的数组变量,则模式删除操作将依次应用于数组的每个成员,并且扩展是结果列表。 [强调。]

相关内容