SEDを使用して最初の一致後に行全体を検索して置き換えますか?

SEDを使用して最初の一致後に行全体を検索して置き換えますか?

次の形式を使用するファイルがあります。

M104 S200
M107
M104 S250
M110
M104 S275

M104私は2番目の項目を一致させ、他の項目も含めるように行全体を書き換える方法を見つけようとしていますM104

頑張った

sed 's/^M104/s/.*/M104 S300/' file - but it replaces all instances of M104
sed '0,/M104/s//M104 S200/' file - leaves the trailing text on the line
  • 他の変更により予期しない結果が発生しました。助けが必要ですか? ;)

ベストアンサー1

Perlがある場合は、次のようにします。

$ perl -pe 'if (/M104/) { $i++; if($i == 2) { $_ = "M104 S999\n" } } ' test.txt
M104 S200
M107
M104 S999
M110
M104 S275

つまり/M104/、一致した場合は増やしてから$i2と同じであることを確認し$i、そうであれば現在の行を置き換えます(末尾の改行を含む\n)。

s/^M104.*/.../そこでsedなどの代替品を使用したい場合は、最後の部分でそれを行うことができます。

-i[extension]Perlには、バックアップファイルの有無にかかわらず内部変更を実行できるsedに似たオプションがあります。

または、環境変数を介してキー値を渡します(スクリプトが簡単になります)。

n=2 repl="S999" perl -pe 'if (/M104/) { $i++; if($i == $ENV{n}) { $_ = "M104 " . $ENV{repl} . "\n" } } ' test.txt

(または、たとえばネストよりも接続を好む場合。perl -pe '/M104/ and $i++ and $i == 2 and $_ = "M104 S999\n" ' test.txt


またはawkから:

$ awk '/M104/ { i++; if (i == 2) $0 = "M104 S999"; } 1' test.txt

ただし、awkには標準の内部オプションはありません。

おすすめ記事