Bash:RegExを使用した文字列の置換/短縮(RegExに失敗)

Bash:RegExを使用した文字列の置換/短縮(RegExに失敗)

Bashを使って文字列を減らしたいです。残念ながら、これは計画通りには進まなかった。前の文字部分だけが欲しいです。残念ながら、以下のバリエーションの1つはまだ同様に機能します。どのように書くと正しく書かれますか?

var="backup_user-data_2101220046.tgz"

var2="${var/_[0-9]{10}.tgz/''}"
var2="${var/'\_[0-9]+\.tgz'/''}"

答え1

ksh93演算子では、${var/pattern/replacement}パターンは正規表現ではなくシェルワイルドカードパターンとして解釈されます。

~(G)ksh93では、それぞれを使用してデフォルト、拡張、または拡張正規表現に切り替えることができるため、~(E)次の~(X)ことができます。

var2=${var/~(E)_[0-9]{10}\.tgz$/}

例えば。または、拡張グローバルモードを使用してください。

var2=${var/%_{10}([0-9]).tgz/}

(と同じですvar2=${var%%_{10}([0-9]).tgz}

bash、ksh93のzshコピー演算子に似ています${var/pattern/replacement}が、ワイルドカード演算子はさらに制限されています。このextglobオプションを有効にすると、拡張演算子はサポートされますが、ksh88ksh93の上位演算子、特に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

完全性のためにzshksh93を複製し、${var/pattern/replacement}optionsを使用してksh88ワイルドカード拡張をサポートしましたが、optionsをkshglob使用する独自の拡張glob演算子がありますextendedglob。これにより ERE に該当するのは{x,y}なので、(#cx,y)次のことができます。

set -o extendedglob
var2=${var/%_[0-9](#c10).tgz}

(3つのシェルのうち、zshこれは0123456789にのみ一致する唯一のものです[0-9]。ksh93とbashは通常⑱のように何千もの文字と一致します。

答え2

「backup_user-data」のみを検索する場合:

$ var="backup_user-data_2101220046.tgz"
$ echo "${var%_*}"
backup_user-data

関連情報