删除前导空格在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]".


以上是删除前导空格在Bash中不起作用的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>