コマンドsed '1!G; h; $!d'はどのようにファイルの内容を逆にしますか?


20

私の質問はsedこの逆greppingの質問に対するこの回答の特定のソリューションに関連しています。sed/ grep私は解読することができませんというソリューションは、次のいずれかです。

sed '1!G;h;$!d' file

誰かがこのコマンドを解読できますか?

VI(M)の知識から、Gはファイルの最終行を示し、sedではbang(!)の後にアドレスが続くgrep -vということは、その行と一致しないということです。しかし、全体として、上記のインラインsedスクリプトは私を超えています。


3
...非常にゆっくり
...-mikeserv

1
mikeservのヒントとして。このトリッキーなsedレシピは、ファイルの行を逆にするための非常に非効率的な方法(O(n ^ 2/2)の複雑さ)であることに注意してください。行数が多いファイルの場合は、非常に遅くなります。より効率的な行順反転の代替方法についてはtac、GNU coreutilsを参照してください。
アリエル

回答:


35

これにより、ファイルが1行ずつ反転します。

sed '1!G; h; $!d' ファイル

まず、sed持っているホールドスペースパターンスペースを。特定のコマンドに集中する前に、それらを区別する必要があります。

ときにsed新しい行を読み込み、それをパターンスペースにロードされます。したがって、その行は新しい行が処理されるたびに上書きされます。一方、ホールドスペースは処理全体で一貫しており、後で使用するために値をそこに保存できます。


コマンドへ:

この文の3つのコマンドがあります1!Gh$!d

  • 1!GG、最初の行を除くすべての行でコマンドが実行されることを意味します(は!否定します1)。ホールドスペースにあるものをパターンスペースG追加することを意味します

  • hすべての行に適用されます。パターンスペースをホールドスペースにコピーします(そして上書きします)。

  • $!d最後の行を除くすべての行に適用されます($最後の行を表し、!否定します)。d行(パターンスペース)を削除するコマンドです。


  1. これで、最初の行が読み取られるとsedhコマンドが実行されます。最初の行がホールドスペースにコピーされます。その後、$!条件に一致するため削除されます。sed2行目から続けます。
  2. 2行目は条件に一致し1!(1行目ではない)、ホールドスペース(1行目)がパターンスペース(2行目)に追加されます。その後、パターンスペースに、改行で区切られた2行目と1行目があります。これで、hコマンドが適用されます(すべての行のように)。パターンスペース内のすべてがホールドスペースにコピーされます。3番目のステートメント($!d)が適用されます。行はパターンスペースから削除されます。
  3. これで、ステップ2はすべての行で完了しました。最後の行にスキップします。
  4. 最後の行($)では、ステップ2のほぼすべてが実行されますが、削除部分(d)は実行されません。sedを使用せずに呼び出すと-n、各入力行の処理の最後にパターンスペースが自動的に出力されます。したがって、削除されない場合、パターンスペースが印刷されます。現在、すべての行が逆の順序で含まれています。

1
@Geekいいえ、hコマンドはパターンスペースをホールドスペースにコピーしsedます。ホールドスペースは終了するまで保持されます。スクリプトの終了後、バイナリが終了したため、すべてがクリアされます。
カオス

2
ホールドスペースをvimのレジスタのように考えることはできますか?それらにも番号が付けられていますか?または、そのうちの1つだけですか?
オタク

2
@Geekではsed、ホールドスペースは1つだけです。それは何かを含むことができる変数のようなものです。
カオス

1
@ user1717828処理しなかった場合、最初の行が印刷されます。sedは呼び出されないため-n、最後を除くすべての行を削除する必要があります。最後の行で、sedはホールドスペースからパターンスペースまですべてを追加します。また、dコマンドは実行されないため、行が印刷されます(この行にはファイル全体が反転されています)。
カオス

1
(1)OPのサブ質問/観察(コメント内)は、「最後の行のhコマンドは一種の無操作です。」(強調を追加し、わずかに言い換えています)。彼は正しいです; ときに処理され、最後の入力の行を、(パターンスペースにそれを追加するために)保持空間を読み出し、その後、保持空間にパターンスペースをコピー再度参照されることはありません。またはと言うこともできます。(2)と言うことで、使用を避けることができます。sedGhsed 'G;$!h;$!d'sed 'G;$!{h;d}'dsed -n 'G;h;$p'
スコット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.