多数のファイルがあり、これらすべてのファイルからいくつかの行を置き換えたいと考えています。行の正確な内容はわかりません。私が知っているのは、すべての行に 2 つの既知の単語が含まれていることだけです。たとえば、'Programmer' と 'Bob' としましょう。したがって、置き換えたい行は次のようになります。
Created by Programmer Bob
Programmer extraordinaire Bob, such an awesome guy
Copyright programmer bob, all rights reserved
これまでのところ、これは簡単に聞こえますが、問題は、たとえばファイルの先頭 (通常、ファイルに関するコメントが見つかる場所) など、行範囲内に含まれる行のみを置き換えたいことです。実際のコードを誤って置き換えたくないので、ファイルの後半部分にある行を置き換えることはできません。
これまでのところ、私は試しました:
find . -exec grep -il -E 'Programmer.*Bob' {} \; | xargs sed -i '1,10 /Programmer.*Bob/Ic\LINE REPLACED'
(grepが無限再帰に遭遇したため、findを使用しています-私は思います。ここでのポイントではありません。)
ただし、c\ (改行) ではアドレス範囲を使用できないようです。構文エラーを自由に指摘してください。ただし、すべてを試しても無駄だったと思います。これは、行番号なしで機能します。
編集:答えを得ましたが、質問を編集して、得た答えを拡張するソリューションを含めることにしました-誰かがこれを役立つと思うかもしれません。
後で、行頭に可能な空白文字とコメント文字を保持したいことに気付きました。このコマンドを使用してそれを達成しました:
find . -exec grep -ilI '.*Programmer.*Bob.*' {} \; xargs sed -i -r '1,10 s/([ \t#*]*)(.*Programmer.*Bob.*)/\1LINE REPLACED/I'
\1 は [ \t#*]* に一致するパターンを保持します。これを ^[ \t#*]* に変更して、パターンを行頭に固定することもできますが、(私は思うに) この現在のバージョンは変更されるでしょう
** Text I don't want to remove ** Programmer Bob
の中へ
** Text I don't want to remove ** LINE REPLACED
どちらが実際に良いかもしれません。(バイナリ ファイルをスキップする -I (大文字の i) フラグも find コマンドに追加しました。)