bash:1つのステップで複数の文字列操作(パラメーター展開)を使用するにはどうすればよいですか?

Aug 15 2020

私が持っているstring=substr1-substr2-substr3.substr4部分文字列が可変長であるところ。から抽出substr3したいので、文字列操作展開stringを使用してそれを行うことを考えています。このアプローチを使用すると、結果の拡張で実行して実行する必要があることは明らかです。その逆も同様です。私の質問は次のとおりです。${string##pattern}${string%pattern}${string##*-}${string%.*}

  1. これが最良の選択ですか?
  2. はいの場合、1つのステップで両方を実行するにはどうすればよいですか?のようなことをしようとしたとき、${string##*-${string%.*}}または${string%.*${string##*-}}文字列全体を取り戻したとき。最初のステップの結果に中間変数を割り当て、それを操作することで、常に2つのステップで抽出を実行できることに気付きました。でも一気にやりたいです。どうすればいいですか?

TIA!

回答

2 ilkkachu Aug 15 2020 at 20:39

与えられた

string=substr1-substr2-substr3.substr4

${string%.*} です

substr1-substr2-substr3

そう、${string##*-${string%.*}}です

${string##*-substr1-substr2-substr3}

これは、の先頭からstring、までのすべてを削除することを意味し-substr1-substr2-substr3ます。ただしstring、の前にダッシュがないため、にはそのような部分文字列はありませんsubstr1。したがって、元の文字列を取得します。

あなたがおそらく欲しいのは

string=substr1-substr2-substr3.substr4
result="${string%.*}" result="${result##*-}"

これはresultcontaingにつながりsubstr3ます。

Zshでは、1つのステップでそれを行うことができます:、しかし、それはBashでは機能しません。result=${${string%.*}##*-}

Bashでは、#またはの右側で拡張を使用するように制限され%ていますが、文字列の最初と最後の両方からパーツを削除する必要があるため、ここでは役に立ちません。


または、$string改行文字が含まれていない場合は、

IFS=.- read -r a b c d <<< "$string"

から読み上げsubstr3ますc

その場合、シェルと文字列のサイズに応じて、の内容は$string一時ファイルに保存されるか、パイプを介して供給され、パイプreadから最初の行が読み取られ、に従って分割され$IFSます。