sedのパターンと一致しない文字列のすべての文字を置き換える方法は?

sedのパターンと一致しない文字列のすべての文字を置き換える方法は?

「something_something_something」などの文字列があります。

文字列には次のパターンが必要です。^[a-zA-Z0-9](-*[a-zA-Z0-9])*

パターンと一致しない文字列のすべての文字を置き換える方法は?

私の例では、私は次のことを行う必要があります:

somethingsomethingsomething

試してみましたがsed -n '/^[a-zA-Z0-9](-*[a-zA-Z0-9])*/p'成功しませんでした。

答え1

まず、sed -Eパターンが拡張正規表現(ERE)として解釈され、一般括弧がグループ化に使用されるようにする必要があります。デフォルトでは、sedのパターンはBRE(Basic Regular Expressions)であり、およびを使用する必要があり\(ます\)

第二に、それsed -n '/.../p'はうまくいきますが、部分的に一致する場合は行全体を印刷します。パターンが最後に固定されている場合は、行全体を削除すると便利です。

パターンに合わない部分を削除するには、次の手順を実行します。

sed -E -e 's/^([a-zA-Z0-9](-*[a-zA-Z0-9])*).*/\1/' input.txt

末尾は.*行全体が一致することを確認し、すべてが最初のキャプチャグループの内容に置き換えられます。 inputの場合、パターンの主要部分と一致しないものとしてsomething_something_something印刷されます。something_

あなたのパターンはと同じように見えます[-a-zA-Z0-9]+。おそらく同様のことを意味するようです[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*。これはfoo、または同じ文字列と一致する必要がありますfoo-bar-doodoo(ただしそうではありませんfoo--bar)。

答え2

sNr(search n replacement)というシェル変数に格納されている別の正規表現を作成し、ここに引用した正規表現のいくつかを追加します。

不明な文字はハッシュ値(#)に置き換えられます。

sNr='
 s@
  \(
   \(
    \(
      [a-zA-Z0-9](-*[a-zA-Z0-9])*
    \)\{1,\}
    #*
  \)*
 \)
 [^a-zA-Z0-9#]
 @\1#@
';

echo something_something_something |
sed -e "
  :loop
    ${sNr//[$IFS]/}
  tloop
"
something#something#something

関連情報