在 zsh 参数扩展中从字符串开头去除任意数量的匹配项

在 zsh 参数扩展中从字符串开头去除任意数量的匹配项

通过参数扩展,我可以删除前导空格,例如

stripped_var=${original_var#[[:blank:]]}

我很熟悉,##而不是#允许匹配最大匹配而不是最小匹配,但还没有找到如何将模式从“一个空白”转换为“任意数量的空白”。

有没有办法允许多个匹配从 的值中去除所有前导空格original_var?理想情况下,我正在寻找一个不涉及启动子进程/子shell的解决方案(即我更喜欢没有 awk、sed 等的解决方案,尽管如果参数扩展不能做到这一点,我也可能会求助于这些)

答案1

你可以使用扩展全局运算符 x#:

x#
(需要设置 EXTENDED_GLOB。)匹配零次或多次出现的模式 x。该运算符具有高优先级; “12#”相当于“1(2#)”,而不是“(12)#”。不带引号的“#”跟在不能重复的内容后面是错误的;这包括空字符串、后跟 '##' 的模式或 KSH_GLOB 模式一部分时的括号(例如,'!(foo)#' 无效且必须替换为 '*(!(foo)) ')。

setopt extended_glob
stripped_var=${original_var##[[:blank:]]#}

答案2

作为@Freddy提到zsh您可以将该模式用作 regexp 的or 's[[:blank:]]#的等效项。[[:blank:]]*ksh*([[:blank:]])

但是 POSIXly,你也可以这样做:

stripped_var=${orginal_var#"${original_var%%[![:blank:]]*}"}

对于等效的awk '{$1=$1};1',即去除前导和尾随空白并将空白序列压缩到一个空格中,您可以执行以下操作:

var=$'  a    b\tc\t\td\t \n\n'
stripped_var=${${=var}}

(这里$stripped_var变成"a b c d")。即执行$IFS-splitting 并再次转换为标量,将元素与 的第一个字符连接起来$IFS

相关内容