Han*_*gon 3 shell bash wildcards variable-substitution
鉴于:
$ shopt -s extglob
$ TEST=" z abcdefg";echo ">>${TEST#*( )z*( )}<<"
>> abcdefg<<
Run Code Online (Sandbox Code Playgroud)
为什么字母“a”前有一个空格?我希望第二个*( )会匹配空间,但它并没有接缝这样做。
我期望相当于:
$ echo ">>$(echo -n "${TEST}" | perl -pe "s/^ *z *//g")<<"
>>abcdefg<<
Run Code Online (Sandbox Code Playgroud)
*( )如果我指定下一个字符(即“a”),则第二个匹配项:
$ shopt -s extglob
$ TEST=" z abcdefg";echo ">>${TEST#*( )z*( )a}<<"
>>bcdefg<<
Run Code Online (Sandbox Code Playgroud)
bash 版本: GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
这是由于非贪婪子字符串删除与您使用的模式类型之间的相互作用。
从bash 手册中,
Run Code Online (Sandbox Code Playgroud)?(pattern-list)匹配给定模式的零次或一次出现。
Run Code Online (Sandbox Code Playgroud)*(pattern-list)匹配给定模式的零次或多次出现。
Run Code Online (Sandbox Code Playgroud)+(pattern-list)匹配给定模式的一次或多次出现。
从我最喜欢的关于 bash字符串操作的解释中,
${string#substring}删除
$substring从前面的最短匹配项$string。
${string##substring}
$substring从 前面删除最长的匹配项$string。
因此,当您指定 时${TEST#*( )z*( )},您是在说:“请删除具有零个或多个空格的最短子字符串, a z,然后是零个或多个空格。
匹配最后一个空格比没有它匹配要长,所以最后一个空格永远不会匹配。
为了解决这个问题,您可以使用${TEST##*( )z*( )}匹配以零个或多个空格结尾的最长前缀或${TEST#*( )z+( )}匹配以一个或多个空格结尾的最短前缀(这在功能上等同于匹配以一个空格结尾的最短前缀)。