sedまたはexを使用してブロック(複数行のコード)を新しいテキストブロック(コード)に置き換えるには?

sedまたはexを使用してブロック(複数行のコード)を新しいテキストブロック(コード)に置き換えるには?

ファイル(シェルスクリプトコード)のテキストの塊を別のテキストの塊に置き換える必要があります。

私にとって印象的なことはsedを使用して複数行の文字列を置き換える方法は?回答者 アンタクそしてマルチライン交換回答者ブルース・エディガー

しかし、それらを使用するにはいくつかの問題があります。

  1. アンタク彼の答えですでに述べたように、1h;2,$H;$!d;g;ファイル全体()をバッファにストリーミングすることはメモリに過負荷がかかるため、大容量ファイルにはお勧めできません。

  2. sedブロック外のテキストを変更せずにそのままにするために、ブロック機能で使用できることがわかります。この機能を使いたいです。しかし、私が使うなら、

    sed -i '/marker1/,/marker2/s/.*/new text (code)/' filename
    

各ストリームに繰り返し新しいテキスト(コード)を挿入します。そのため、提案のようなものを使用してビジュアルブロックをストリームにストリーミングする必要がありました。アンタク以前はブロック(フルファイルではありません)用でした。

  1. 言ったようにブルース・エディガーexドットで始まるアドインを試すことは可能ですが、新しいテキスト(コード)にはドットで始まる行が含まれており、これは追加の構文ではドットと見なすことができます。このような場合にはどのように使用する必要がありますか?a.

  2. ex「行数dd」は複数行を削除できますが、/marker1/と/marker2/の間に固定されていない(変更された)行数のブロックがあり、新しいテキスト(コード)に置き換えたい場合はどうすればよいですか?

答え1

使用することをお勧めしますhangeコマンド(デフォルトではDエレテプラス保留(追加は、目的の範囲の最後の行にのみ適用されますが)。

sed -i '/marker1/,/marker2/c\
New text 1\
New text 2' filename

sedここでは、内部編集()にGNU構文が使用されます-i。それ以外の場合、コマンドはc標準的で移植可能です。 GNUsedサポート:

sed '/marker1/,/marker2/cNew text 1\
New text 2' filename

非標準拡張として。

改行およびバックスラッシュ文字は、代替テキストでエスケープ処理(バックスラッシュを使用)する必要があります。

答え2

GNU sedの使用

一致する行から始まり、一致する行3まで続く行を置き換えるには、次の手順を実行します。5New Code

$ seq 8 | sed '/3/,/5/{/5/ s/.*/New Code/; t; d}'
1
2
New Code
6
7
8

range にある行の場合は、/3/,/5/行が一致するか5(つまり、グループの最後の行か) テストし、そうであれば insert に置き換えますNew Code。置き換えが行われると、このコマンドはsedにコマンドの終わり(tこの場合はNew Code印刷されます)にジャンプするように指示します。それ以外の場合、このdコマンドはsedにその行を削除するように指示します。

他の行はすべて正常に印刷されます。

ファイルを現在の場所から変更するには、-i次のオプションを使用できます。

sed -i.bak '/3/,/5/{/5/ s/.*/New Code/; t; d}' file

awkを使う

awkを使って同じことをします。

$ seq 8 | awk '/3/,/5/{if (!f)print "New Code"; f=1; next}; 1'
1
2
New Code
6
7
8

awkコマンドは範囲内の行を特別に処理します/3/,/5/。範囲内の行の場合はf0かどうか(つまり真であれば!f)テストし、そうであれば印刷New Codeして1に設定し、残りのfコマンドをスキップしてその行にnext移動します。

範囲外の行では、/3/,/5/ジャンプが発生せずに行が1印刷されます。もっと具体的に言えば1条件だ。10 ではないため、条件は true と評価されます。条件に関連するジョブがないため、基本ジョブ、すなわちラインを印刷するジョブが実行される。これは1print-the-lineの略です。

ファイルを適切に変更するには、GNU 4.1以降でこの-i inplaceオプションを使用できます。awk

awk -i inplace '/3/,/5/{if (!f)print "New Code"; f=1; next} 1' file

答え3

上記の議論に基づいて解決策を見つけました。ex

seq 15 > test1.txt
ex test1.txt << EOEX
/^7/,/^9/c
abcd
123
.xyz
hfr4
.
w!
q
EOEX
cat test1.txt

上記

1
2
3
4
5
6
abcd
123
.xyz
hfr4
10
11
12
13
14
15

ありがとうg男性変更コマンドを理解し、ポイントを明確にします。sedどちらもexほぼ同様の変更コマンド構文を共有します(削除コマンド、追加コマンドなどに適用されます)。

関連情報