sed "e"フラグと "g"フラグは一緒に機能しません。

sed "e"フラグと "g"フラグは一緒に機能しません。

これを考慮すると:

echo AAA | sed -r 's/A/echo B/ge'

わかりました:

Becho Becho B

「BBB」を手に入れると思いました。 GNU sed バージョン 4.2.1 の場合です。何が起こっていますか?どのように実行フラグを使用し、1行で複数の置換を実行できますか(Perlなどではなくシェルで)。

答え1

これらのフラグは、予想されるものとは反対の方法で一緒に動作します。これ文書/e、参考までに:

このコマンドを使用すると、シェルコマンドの入力をパターンスペースにパイプできます。置換が行われると、パターン空間内のコマンドが実行され、その出力がパターン空間を置き換えます。末尾の改行は抑制されます。実行するコマンドにヌル文字が含まれている場合、結果は定義されません。これはGNU sed拡張です。

文が少し複雑ですね。つまり、s///その行のコマンドが完了した後に変更が発生した場合(新しい)、行がコマンドとして実行され、その出力がその行を置き換えるために使用されます。

したがって、与えられたコマンドについて:

echo AAA | sed -r 's/A/echo B/ge'

まず、それぞれAecho B、およびそれから結果をコマンドとして実行します。大まかに言えば、次のような効果があります。

echo AAA | sed -r 's/A/echo B/g' | sh

GNUはsed希望のモードを直接サポートしていませんが、必要に応じてより複雑なスクリプトを使用して偽にすることができます。または、コマンド/eに対するPerlの修飾子は、ユーザーsが探している動作を持ちますが、代わりにPerl式を使用します。

答え2

あなたはい複数の置換をインポートしますが、複数の実行をインポートしません。すべての交換が完了すると、パターンが実行されます。

eフラグなしの結果

echo AAA | sed -r 's/A/echo B/g'

はい

echo Becho Becho B

コマンドラインを実行すると、これが発生しますするe次のフラグが含まれています。

echo 'Becho Becho B'

答え3

GNU sed の 's' コマンドと 'e' フラグを使用して 'AAA' から 'BBB' を取得するには:

echo AAA | sed -re 's/A/echo -n B;/ge'

「AAA」は「echo -n B;echo -n B;」 echo -n B; 'に置き換えられます。これにより、実行時に3つの連続したechoコマンドが生成され、各コマンドはグローバルマッチングに対応します。 '-n'はエコー出力から改行文字を省略し、 'B'が1行で終わるようにします(ただし、sedは最終的にパターンスペースを印刷するときに改行文字自体を追加します)。

答え4

何:

(1)説明した正確なユースケースは、以下で処理できます。

echo AAA | sed 's/A/B/g'

(2)実行に必要な場合(単純なエコーより高度な使用のため)、このeフラグを最後のステップとして使用できます。

echo AAA | sed -r 's/A/B/g;s/(.*)/echo \1/e'

(3) 何かを置き換える場合にのみ最初の代替コマンドを実行するには、ブランチを使用します。

echo AAA | sed -r 's/A/B/g;te;b;:e;s/(.*)/echo \1/e'

sed上記のように、これはGNUにのみ適用されます。 BSD sed(少なくとも私が持っているバージョン)はこの-rオプションをサポートしておらず、文字列の終わりはブランチ名の後になければなりません。 (パラメータを使用して複数のオプションを追加すると、この最後の問題を解決できます-e。)

与えられた入力(AAA)に対して、これら3つのシングルライナーはすべて機能的に同じです。ただし、echoコマンドが別のものに変更された場合、またはオプションが-nに渡された場合は、sed違いを確認できます。

関連情報