sed を使用してファイル内の最初の出現のみを置換するにはどうすればよいでしょうか? 質問する

sed を使用してファイル内の最初の出現のみを置換するにはどうすればよいでしょうか? 質問する

既存の #includes の前に追加の include ディレクティブを追加して、多数の C++ ソース ファイルを更新したいと思います。このようなタスクでは、通常、sed を使用した小さな bash スクリプトを使用してファイルを書き換えます。

sedファイル内の文字列をすべて置き換えるのではなく、最初に出現した文字列だけを置き換えるにはどうすればよいですか?

もし私が

sed s/#include/#include "newfile.h"\n#include/

すべての #includes を置き換えます。

同じことを達成するための代替案の提案も歓迎します。

ベストアンサー1

sed「Apple」の最初の出現のみを「Banana」に置き換えるスクリプト

     Input:      Output:

     Apple       Banana
     Apple       Apple
     Orange      Orange
     Apple       Apple

これは簡単なスクリプトです:編集者注: GNU sedでのみ動作します。

sed '0,/Apple/{s/Apple/Banana/}' input_filename

最初の 2 つのパラメータ0と は/Apple/範囲指定子です。 はその範囲内で実行されるものです。したがって、この場合は「先頭 ( ) から の最初のインスタンスまでのs/Apple/Banana/範囲内で、を に置き換えます。最初のものだけが置き換えられます。 」0AppleAppleBananaApple

背景:従来のsed範囲指定子はまた「ここから始まる」と「ここから終わる」(両端を含む)の 2 つの正規表現があります。ただし、最も小さい「始まり」は最初の行(1 行目)であり、「ここから終わる」が正規表現である場合、「始まり」の次の行でのみ一致が試行されるため、最も早い終了は 2 行目になります。したがって、範囲は両端を含むため、可能な最小の範囲は「2 行」であり、最小の開始範囲は 1 行目と 2 行目の両方です(つまり、1 行目に出現すると、2 行目の出現も変更されますが、この場合は望ましくありません)。sedは、範囲の終了を にすることができるようにGNU「疑似」として start を指定できる独自の拡張機能を追加し、正規表現が最初の行に一致する場合は「最初の行のみ」の範囲を許可します。line 0line 1

または簡略化されたバージョン (空の RE は、//その前に指定されたものを再利用することを意味するため、これは同等です):

sed '0,/Apple/{s//Banana/}' input_filename

そして中括弧はオプションコマンドの場合はs、これも同等です:

sed '0,/Apple/s//Banana/' input_filename

これらはすべて GNU でsedのみ動作します。

homebrew を使用して OS X に GNU sed をインストールすることもできますbrew install gnu-sed

おすすめ記事