最後の一致を置き換えるためにシェル変数置換を使用する方法はありますか?

最後の一致を置き換えるためにシェル変数置換を使用する方法はありますか?
% x=abracadabra
% echo ${x//a/o}
obrocodobro

吸入… …

交換する方法はありますか?最後sedパターンの発生を置き換えるためにシェルを使用しますか(IOW、、などawkを押し出さないでくださいperl)?

答え1

注:これは後続の発生を置き換えます。 「最後の発生」とまったく同じではありません。

~からBashリファレンスマニュアルセクション3.5.3シェルパラメータの拡張 :

${parameter/pattern/string} 

ファイル名拡張と同様に、パターンを拡張してパターンを生成します。パラメータが拡張され、パターンとその値と最も長い間一致する項目が文字列に置き換えられます。パターンが「/」で始まる場合、そのパターンはすべて文字列に置き換えられます。通常、最初の発生のみが置き換えられます。パターンが「#」で始まる場合は、パラメータの拡張値の先頭と一致する必要があります。パターンが「%」で始まる場合は、パラメータの拡張値の終わりと一致する必要があります。文字列が空の場合、一致するパターンが削除され、次の/パターンが省略される可能性があります。 nocasematchシェルオプションが有効になっている場合(Shoptbuildinのshoptの説明を参照)、アルファベット文字の大文字と小文字に関係なく一致が実行されます。パラメータが「@」または「の場合'を使用すると、各位置引数に代替操作が順番に適用され、拡張が結果リストになります。パラメータが配列変数の場合、下付き文字は「@」または「'、置換操作が配列の各メンバーに順番に適用され、拡張が結果リストです。

だから

$ x=abracadabra
$ echo "${x/%a/o}"
abracadabro

答え2

シェルの置き換えではこれを行うことができますが、少し面倒です。デフォルトでは、パターンの後ろのすべてをキャッチするのではなく、パターンが代替アイテムを挿入する前にすべてをキャッチできます。あなたの例は次のとおりです。

    x=abracadabra
    echo "${x%a*}o${x##*a}"

編集:またはSteeldriverがコメントで提案したようにしてください。

関連情報