Bash
bash - extglob 第二個“零或多個”運算符不工作
鑑於:
$ shopt -s extglob $ TEST=" z abcdefg";echo ">>${TEST#*( )z*( )}<<" >> abcdefg<<
為什麼字母“a”之前有一個空格?我希望第二個
*( )
會匹配空間,但它並沒有接縫這樣做。我期望相當於:
$ echo ">>$(echo -n "${TEST}" | perl -pe "s/^ *z *//g")<<" >>abcdefg<<
*( )
如果我指定下一個以下字元(即“a”),則第二個匹配:$ shopt -s extglob $ TEST=" z abcdefg";echo ">>${TEST#*( )z*( )a}<<" >>bcdefg<<
重擊版本:
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
${TEST#...}
匹配最短的字元串,即 z 後跟零個空格。你需要${TEST##...}
,最長的匹配。
這是由於非貪婪子字元串刪除和您使用的模式類型之間的相互作用。
從bash 手冊中,
?(pattern-list)
匹配給定模式的零次或一次出現。
*(pattern-list)
匹配給定模式的零次或多次出現。
+(pattern-list)
匹配給定模式的一次或多次出現。
從我最喜歡的關於 bash字元串操作的解釋中,
${string#substring}
$substring
刪除 的前面的最短匹配項$string
。
${string##substring}
$substring
從 的 前面刪除最長的匹配項$string
。因此,當您指定 時
${TEST#*( )z*( )}
,您是在說:“請刪除具有零個或多個空格的最短子字元串 az
,然後是零個或多個空格。最後一個空格的匹配比沒有它的匹配要長,所以最後一個空格永遠不會匹配。
為了糾正這個問題,您可以使用
${TEST##*( )z*( )}
匹配以零個或多個空格結尾的最長前綴,或者${TEST#*( )z+( )}
匹配以一個或多個空格結尾的最短前綴(這在功能上等同於匹配以一個空格結尾的最短前綴)。