今このようなことを経験したのに理解できません。
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/'
perl
GNUのサイズは制限されませんが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