删除前导空格在Bash中不起作用
我在 Bash 中有一个字符串,它可能以也可能不以任意数量的前导空格开头,例如
" foo bar baz"
" foo bar baz"
"foo bar baz"
我想从字符串中删除“foo”的第一个实例,以及任何前导空格(可能没有)。
按照这个问题的建议,我尝试了以下方法:
str=" foo bar baz"
regex="[[:space:]]*foo"
echo "${str#$regex}"
echo "${str#[[:space:]]*foo}"
如果 str 有一个或多个前导空格,那么它将返回我想要的结果,即_bar baz(下划线 = 前导空格)。如果字符串没有前导空格,则不会执行任何操作并返回foo bar baz. 两个“回声”在这里返回相同的结果。
我的理解是使用*after[[:space:]]应该匹配零个或多个 [[:space:]] 实例,而不是一个或多个。我在这里错过了什么或做错了什么?
编辑
@Raman - 我尝试了以下方法,但它们也不起作用:
echo "${str#[[:space:]]?foo}"
echo "${str#?([[:space:]])foo}"
echo "${str#*([[:space:]])foo}"
无论是否有尾随空格,所有三种解决方案都不会删除 'foo'。唯一可行的解决方案是我用星号发布的解决方案 - 当有尾随空格时它会删除 'foo',但没有时则不会。
回答
最好的做法是使用参数扩展(使用扩展的 globs),如下所示:
# Make sure extglob is enabled
shopt -s extglob
str=" foo bar baz"
echo "${str##*([[:space:]])}"
这使用扩展的 glob*([[:space:]])和##参数扩展(贪婪匹配)。
编辑。由于您的模式具有后缀foo,因此您无需使用贪婪匹配:
echo "${str#*([[:space:]])foo}"
足够。
笔记。你也可以放入foo一个变量,但要小心,你必须引用它:
pattern=foo
echo "${str#*([[:space:]])"$pattern"}"
将工作。如果扩展pattern包含 glob 字符,您必须引用它。例如当pattern="foo[1]".