Bash:使用 RegEx 进行字符串替换/缩短字符串(RegEx 失败)

Bash:使用 RegEx 进行字符串替换/缩短字符串(RegEx 失败)

我想用 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

为了完整性,虽然zshdid 复制了 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

相关内容