我想用 Bash 缩短字符串。不幸的是,这并没有按计划进行。我只想有前面的字母部分。不幸的是,下面的变体之一仍然工作相似。应该如何正确书写呢?
var="backup_user-data_2101220046.tgz"
var2="${var/_[0-9]{10}.tgz/''}"
var2="${var/'\_[0-9]+\.tgz'/''}"
答案1
在${var/pattern/replacement}
ksh93 运算符中,模式被解释为 shell 通配符模式,而不是正则表达式。
在 ksh93 中,您可以分别使用 , 切换到基本、扩展或增强正则表达式~(G)
,~(E)
因此~(X)
您可以执行以下操作:
var2=${var/~(E)_[0-9]{10}\.tgz$/}
例如。或者使用其扩展的 glob 模式:
var2=${var/%_{10}([0-9]).tgz/}
(与...一样var2=${var%%_{10}([0-9]).tgz}
)
bash
,就像从 ksh93zsh
复制${var/pattern/replacement}
操作符一样,但它的通配符操作符受到更多限制。启用该extglob
选项后,它支持 的扩展运算符ksh88
,但不支持 ksh93 的更高级运算符,尤其不支持 ksh93 的扩展运算{x,y}(...)
符。
但它确实支持这+(...)
一点。所以你可以这样做:
shopt -s extglob
var2=${var/%_+([0-9]).tgz/}
在 中bash
,为了扩展正则表达式支持,您可以使用=~
其[[...]]
构造的运算符:
regexp='^(.*)_[0-9]{10}\.tgz$'
if [[ $var =~ $regexp ]]; then
var2=${BASH_REMATCH[1]}
else
var2=$var1
fi
为了完整性,虽然zsh
did 复制了 ksh93 的${var/pattern/replacement}
并且使用 选项支持 ksh88 通配符扩展kshglob
,但它有自己的扩展 glob 运算符,使用extendedglob
选项。有了这些,ERE 的等价物{x,y}
是(#cx,y)
,因此您可以执行以下操作:
set -o extendedglob
var2=${var/%_[0-9](#c10).tgz}
(请注意,在这三个 shell 中,zsh
这是唯一一个[0-9]
仅匹配 0123456789 的 shell。ksh93 和 bash 通常匹配数千个字符,例如 ⑱,
答案2
如果您只想检索“backup_user-data”:
$ var="backup_user-data_2101220046.tgz"
$ echo "${var%_*}"
backup_user-data