一部のテキストが続く文字列で複数のスペースを置き換えるグローバルパターン

一部のテキストが続く文字列で複数のスペースを置き換えるグローバルパターン

パターンを置き換えるために、複数のスペースとテキスト行の一部のテキストが一致するグローバルパターンを構成したいと思います。

たとえば、次の文字列を考えてみましょう。

str="Here is a list of functions  Marionette Recutils"

2つ以上のスペースといくつかのテキストで構成される最後の部分を置き換えたいと思います。つまり、グローバルパターンマッチングで" Marionette Recutils"

複数のスペースといくつかのテキストが一致するパターンが必要です。次のパターンを思い出しました。

ptrn="[[:blank:]]+([[:blank:]])+([[:graph:]])"

パラメータ置換パターンが部分文字列と一致して、前と後の両方の文字を許可できますか?

答え1

グローバルパターンを持つ2つ以上の項目には、次のものを使用できます。

  • {2,}(something)ksh93から
  • (something)(#c2,)存在するzsh -o extendedglob
  • something(something)##存在するzsh -o extendedglob
  • something+(something)kshまたはbash -O extglob(または)からzsh --emulate ksh
  • somethingsomething*(something)その場合も同様です。

だからバッシュでは:

shopt -s extglob
str="Here is a list of functions  Marionette Recutils"
newstr=${str/ +( )*/REPLACEMENT}

または

newstr=${str/[[:blank:]]+([[:blank:]])*/REPLACEMENT}

POSIX shでは、次のこともできます。

case str in
  (*[[:blank:]][[:blank:]]*) newstr=${str%%[[:blank:]][[:blank:]]*}REPLACEMENT;;
  (*) newstr=$str;;
esac

この${str%%pattern}演算子(元のkshに由来)は、最後のパターンに一致する最も長い文字列を削除します$str

答え2

私はこれがいくつかの極端なケースを処理できないと確信していますが、それを管理しました...

# echo "Here is a list of functions  Marionette Recutils" | sed "s/  .*//"

Here is a list of functions

答え3

簡単に:純粋なBashでは:out=${str/* /}

長い:

str="Here is a list of functions  Marionette Recutils"
echo "${str/*  /}"   # <-- This way
# Out: Marionette Recutils

からman bash/パラメータ拡張

${parameter/pattern/string}

Pattern  substitution.   The pattern is expanded to produce a
pattern just as in pathname expansion, Parameter is  expanded
and  the  longest  match  of pattern against its value is re‐
placed with string.

答え4

文字クラスについて混乱した点[:blank:]変える角かっこ式なので、全体には2つの同心角かっこセットがあります[[:blank:]]。これはまた、[[:blank:][:lower:]](単一のスペースまたは小文字)または[-_[:alpha:]](ダッシュ、アンダースコア、または文字)などの組み合わせ、または[^[:blank:]](すべての文字)のように否定される可能性があることを意味します。いいえ空白)。

したがって、次のように使用できます。

ptrn="[[:blank:]][[:blank:]]*"
echo "${str%$ptrn}"

それ以外の場合:

echo "${str%[[:blank:]][[:blank:]]*}"

関連情報