フラグpを指定したsed substitutionコマンドが、変更された出力を2回出力するのはなぜですか?


3

私のa.txtには次のものが含まれています。

apple
123
pear
1234

このコマンドを以下で実行すると、

sed 's/123/AAA/p' a.txt

私は得ると思った

apple
123
AAA
pear
1234
AAA4

sedはデフォルトで各行を自動的に印刷するためです。そして、パターン空間で修正された後の修正された出力を期待していました。しかし、実際の出力では、置換が2回出力されます。

apple
AAA
AAA
pear
AAA4
AAA4

何故ですか?


1
印刷はプロセスサイクルの最後に行われるためですか?
スチールドライバー

回答:


7
sed 's/123/AAA/p' a.txt

この式には2つのコマンドが含まれます

  • s/123/AAA/意味を持つ行を検索123し、交換する123AAA、それが発生し、それらのライン上の最初のインスタンスで。デフォルトでは、sedすべての行を印刷するため、ストリーム全体が変更されて印刷されます

  • pつまり、パターンスペースを印刷します。を呼び出した時点でp、パターンスペースには変更された行が含まれているため、再び印刷されます。

sand の組み合わせは、p通常、で使用-nされs、そのために変更されたストリームの行のみを印刷する場合に使用されます。

コマンドの順序が重要です。コマンドで、p最初に配置すると、変更されていないストリームが、期待どおりに出力されます。

$ sed 'p;s/123/AAA/' a.txt
apple
apple
123
AAA
pear
pear
1234
AAA4

ここでを呼び出すpとき、パターンスペースはファイル全体です。これは、その一部を指定しておらず、変更されていないためです。また、このsコマンドはファイル全体を出力しますが、ファイルを変更するため、変更されたストリームと変更されていないストリームが2回表示されます。1

したがって、おそらくsed式のコマンドは左から右に累積的に適用されると考えるのに役立ちます.steeldriverが言ったように、この場合に得られる出力pは、s選択に使用された後、サイクルの終わりに適用されるためですファイルの一部を変更します。


1元々、私が持っていたコマンドはでしたsed 'ps/123/AAA/' a.txt。同様に親切に指摘mxmlnknによるコメントは、このコマンドはGNUでは動作しませんsed。私はBusyBoxをsed(AndroidのTermuxで)使用していましたがsed、UbuntuのGNU でコマンドを適切にテストしませんでした(悪い!)。しかしsed、ここでセミコロンを必要とする点でGNU が他のGNU と異なることを知ることは興味深いです。


2
sed 'ps/123/AAA/' a.txt私にはうまくいきません。与えるsed: -e expression #1, char 2: extra characters after commandsed -n 'p; s/123/AAA/p' a.txt質問で予想される出力が正確に得られることに注意してください。
mxmlnkn

1
@mxmlnknはこのコメントを本当にありがとう!チャットでEliahケーガンからの助けを借り、私は私が私の答えでその間違ったコマンドになってしまったのか悟りました。あなたが最後に与えたコマンドに関して、それを含めることは私の答えの理由を超えているように感じます、そして私はそれが既に支持されているので私の答えをあまり修正したくはありませんが、多分質問は別のものから利益を得るでしょう答え、投稿したい場合は?(それ以外の場合、回答をさらに変更する必要があると思われる場合は、お気軽に提案または編集してください)
Zanna

1
GNU sedは実際にはセミコロンを必要としません。また、改行を許可します。;)ただし、セミコロンAFAICTはPOSIXによって義務付けられている唯一のものであり、したがってすべての準拠実装で動作することが保証されています。
fkraiem
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.