sed パターン空間とホールド空間

sed パターン空間とホールド空間

今このようなことを経験したのに理解できません。

sed -n '1h; 1!H; ${ g; s/foo\nbar/bla\nblub/ p }' file.

猫ファイルはどこにありますか?

 foo
 foo
 bar

なぜこれが起こるのでしょうか?1!H私は1hパターン空間を上書きして1!H何の役にも立たないからです。

しかし、sed onelinerはうまくいくようです。

答え1

バラより@manatworkからの返信実用的な理由が1h;1!Hありますが、移植性に関するメモを追加したいと思います。

標準および移植可能な構文は次のとおりです。

sed -n '1h; 1!H; ${ g; s/foo\nbar/bla\
blub/p;}'

sedそれ以外の場合、従来のUnix実装など、ほとんどの実装では機能しません。

これは\nコマンドの左側で理解できますが、s右側ではバックスラッシュ文字を使用し、その後に実際の改行文字が続く必要があります。また、;コマンドとの間にスペースを含める必要があり、その前にスペースを含めないでください。s}p

予約済みスペースの代わりにパターンスペースにファイルの内容を保存することもできます。

sed -n '
  :1
  $!{
   N;b1
  }
  s/foo\nbar/blah\
blup/p'

ただし、モードとストレージの場合、ほとんどのsed非GNU実装にはこれらのファイルサイズに制限があるため、ほとんどの実装では小さなファイルしか処理できません(POSIXでは8kiBのデータのみを保存できるはずです)。

移植性を持たせるには、以下を使用することをお勧めしますperl

perl -0777 -ne 'print if s/foo\nbar/blah\nblup/'

perlGNUのサイズは制限されませんがsed、各プロセスのメモリ使用量に制限を設定しないと、システムメモリがすべて使用されるため、システムのパフォーマンスに影響を与える可能性があることに注意してください。

答え2

1!Hがある理由は、1hがパターン空間を覆い、1!Hが役に立たないからです。

同じ入力ラインで実行されないため、上書きは発生しません。

1h   # when input line number is 1, copy pattern space to hold space
1!H  # when input line number is not 1, append pattern space to hold space

これは次の理由で必要ですinfo sed

`H'
     Append a newline to the contents of the hold space, and then
     append the contents of the pattern space to that of the hold space.

したがって、すべての行を追加するだけで、H最初の行の前に改行が追加されます。

bash-4.2$ seq 3 | sed -n 'H; ${g; p;}'

1
2
3
bash-4.2$ seq 3 | sed -n '1h; 1!H; ${g; p;}'
1
2
3

関連情報