必要な策略には 2 つの部分があります。
閉じた角括弧に到達したら置換を停止します (ただし、行で繰り返し実行します)。
s/\(\[[^] ]*\) /\1_/g
これは、開き角括弧の後に、空白でも閉じ角括弧でもない 0 個以上の文字が続くものと一致します。グローバル接尾辞は、行の左角括弧で始まり、最終的に空白または右角括弧が続くすべてのシーケンスにパターンが適用されることを意味します。また、この正規表現は ' ' を変更しないことに注意してください。[single-word] and context
元の正規表現はそれを ' ' に変換し[single-word]_and context
ますが、これは演習の目的ではありません。
sed を取得して、この検索が開始された場所から検索を繰り返します。残念ながら、それを行う本当に良い方法はありません。Sed は常に、置換されたテキストの後で検索を再開します。これは、それを望まない場合の 1 つです。代用操作を繰り返すだけで済む場合もあります。この場合、置換が成功するたびにそれを繰り返す必要があり、置換がなくなると停止します。
あまり知られていない 2 つの操作sed
は、 ' ' コマンド:label
と ' t
' コマンドです。ただし、それらは Unix の第 7 版 (1978 年頃) に存在していたため、新しい機能ではありません。b
1 つ目は、' ' (ここでは不要) または ' t
'でジャンプできるスクリプト内の位置を単純に識別します。
[2addr]t [label]
:
入力行の最新の読み取りまたは ' ' 関数の実行以降に置換が行われた場合、ラベルを持つ' ' 関数に分岐しt
ます。ラベルが指定されていない場合は、スクリプトの最後に分岐します。
すばらしい: 必要なもの:
sed -e ':redo; s/\(\[[^] ]*\) /\1_/g; t redo' data.file
ただし、そのような 1 行ですべてが機能するわけではありません (少なくとも、MacOS X ではそうではありません)。ただし、これは見事に機能しました。
sed -e ':redo
s/\(\[[^] ]*\) /\1_/g
t redo' data.file
または、コメントに記載されているように、3 つの個別の「-e」オプションを記述できます (これは MacOS X で動作します)。
sed -e ':redo' -e 's/\(\[[^] ]*\) /\1_/g' -e 't redo' data.file
次のデータ ファイルを指定します。
a line with [one blank] word inside square brackets.
a line with [two blank] or [three blank] words inside square brackets.
a line with [no-blank] word inside square brackets.
a line with [multiple words in a single bracket] inside square brackets.
a line with [multiple words in a single bracket] [several times on one line]
表示されている sed スクリプトからの出力は次のとおりです。
a line with [one_blank] word inside square brackets.
a line with [two_blank] or [three_blank] words inside square brackets.
a line with [no-blank] word inside square brackets.
a line with [multiple_words_in_a_single_bracket] inside square brackets.
a line with [multiple_words_in_a_single_bracket] [several_times_on_one_line]
そして最後に、質問の細字を読んで、各行の最初の角括弧で囲まれたフィールドでのみこれを行う必要がある場合は、一致を開始する角括弧の前に開いた角括弧がないことを確認する必要があります. このバリアントは動作します:
sed -e ':redo' -e 's/^\([^]]*\[[^] ]*\) /\1_/' -e 't redo' data.file
(「g」修飾子はなくなりました - ループを考えると、おそらく他のバリアントでは必要ありません。その存在により、プロセスがわずかに効率的になる可能性がありますが、それを検出することは本質的に不可能である可能性が最も高いでしょう。パターンは現在行頭 (キャレット) に固定され、最初の左角括弧の前に左角括弧以外の文字が 0 個以上含まれています。)
出力例:
a line with [two_blank] or [three blank] words inside square brackets.
a line with [no-blank] word inside square brackets.
a line with [multiple_words_in_a_single_bracket] inside square brackets.
a line with [multiple_words_in_a_single_bracket] [several times on one line]