Sed - ファイル内の単語の最初のkインスタンスを置き換えます。

Sed - ファイル内の単語の最初のkインスタンスを置き換えます。

k私は単語の最初のインスタンスだけを変更したいと思います。

どうすればいいですか?

例えば。ファイルにfoo.txt「linux」という単語が100回含まれているとします。

最初の50項目を交換するだけです。

ベストアンサー1

sed以下の最初の部分では、行で最初のk回発生する項目を変更する方法について説明します。 2番目の部分は、表示される行に関係なく、ファイル内の最初のk個の項目のみを変更することによってこのアプローチを拡張します。

ライン中心ソリューション

標準sedには、1行目からk番目に表示される単語を置き換えるコマンドがあります。たとえば、3の場合k

sed 's/old/new/3'

または、すべての項目を次のように置き換えることができます。

sed 's/old/new/g'

これらのどれもあなたが望むものではありません。

GNUは、sedk番目の発生とすべての後続のケースを変更する拡張機能を提供します。たとえば、kが3の場合:

sed 's/old/new/g3'

これらを組み合わせて、好きなことをすることができます。最初の3つの項目を変更するには:

$ echo old old old old old | sed -E 's/\<old\>/\n/g4; s/\<old\>/new/g; s/\n/old/g'
new new new old old

ここでwhere\nは一行には決して現れないので便利です。

説明する:

3つの代替コマンドを使用しますsed

  • s/\<old\>/\n/g4

    これは、4番目とそれ以降のすべての項目old\n

    \<単語の始まりと\>終わりを一致させるための拡張正規表現機能。これにより、完全な単語のみが一致します。拡張正規表現には-Eオプションが必要ですsed

  • s/\<old\>/new/g

    最初の3つの項目だけを保持すると、oldすべて置き換えられますnew

  • s/\n/old/g

    4番目と残りのすべての発生は最初のステップoldに置き換えられます。\nこれにより元の状態に復元されます。

非GNUソリューション

GNU sedを使用できず、の最初の3つの項目をに変更するには、次の3oldつのコマンドをnew使用しますs

$ echo old old old old old | sed -E -e 's/\<old\>/new/' -e 's/\<old\>/new/' -e 's/\<old\>/new/'
new new new old old

kこの方法は数字が小さい場合はうまく機能しますが、大きな数字に拡張するとうまく機能しませんk

GNU以外の一部のsedはセミコロンを使用したコマンドの結合をサポートしていないため、ここの各コマンドには独自の-eオプションがあります。sed単語の境界記号\<とをサポートしていることを確認することもできます\>

ファイル中心のソリューション

sedにファイル全体を読み、交換を実行するように指示できます。たとえば、oldBSD スタイルを使用して sed の最初の 3 つの項目を置き換えるには、次のようにします。

sed -E -e 'H;1h;$!d;x' -e 's/\<old\>/new/' -e 's/\<old\>/new/' -e 's/\<old\>/new/'

sed コマンドはH;1h;$!d;xファイル全体を読み込みます。

上記はGNU拡張を使用していないため、BSD(OSX)sedで動作する必要があります。このアプローチには、sed長い行を処理するためのメソッドが必要です。 GNUはsed大丈夫でしょう。 GNU以外のバージョンを使用している人は、sed長い行を処理する能力をテストする必要があります。

gGNU sedを使用すると、上記のトリックをさらに一歩進めることができますが、最初の3つの項目を置き換えることができます\n\x00

sed -E -e 'H;1h;$!d;x; s/\<old\>/\x00/g4; s/\<old\>/new/g; s/\x00/old/g'

このアプローチはスケーラビリティが高く、k規模も大きくなります。しかし、\x00元の文字列にはないとします。\x00bash文字列に文字を入れることは不可能なので、これは通常安全な仮定です。

おすすめ記事