sed-4.0.7のアドレス拡張(STEP)
GNU sedはアドレスにステップを指定できる。指定方法はアドレスんところを'
これを使うと簡単に「何行ごとになんとか」ができるのでたとえばプログラムからのダム出力をN行ごとに区切ったりとか出来る。
% sed '1~3i---' eplx.out --- 77050000 pl_out: 000000 77100000 pl_out: 000000 84600000 pl_out: 000110 --- 84650000 pl_out: 000110 86000000 pl_out: 000101 86050000 pl_out: 000101 --- 87400000 pl_out: 000100 87450000 pl_out: 000100 :
とかできて便利。なんだけど、んんん、なんか一行目の --- 邪魔だぞ、とか思い始めたのが思えば転落開始のサインだった。
% sed '4~3i---' eplx.out 77050000 pl_out: 000000 77100000 pl_out: 000000 84600000 pl_out: 000110 84650000 pl_out: 000110 86000000 pl_out: 000101 86050000 pl_out: 000101 --- 87400000 pl_out: 000100 87450000 pl_out: 000100 :
あれれれれれれっれれれっれっれっれっっ?なんで4行目出ないの?
実はライセンスの関係でEDAマシン上でやっていたのだけれど、sedのバージョンが 4.0.7だった。しかしこの仕様、まったくもって、なんじゃこりゃー、とカッとなって思わずソースを拾ってみてしまった。
case addr_is_num_mod: if (addr->addr_number < addr->addr_step) return (addr->addr_number == input->line_number%addr->addr_step); /* addr_number >= step implies we have an extra initial skip */ // ← 犯人 if (input->line_number < addr->addr_number) // ← 犯人 return FALSE; /* normalize */ addr->addr_number %= addr->addr_step; return (addr->addr_number == 0);
なんじゃこりゃー。
無論、新しいバージョンではちゃんと普通に直ってます。
case ADDR_IS_NUM_MOD: return (input->line_number >= addr->addr_number && ((input->line_number - addr->addr_number) % addr->addr_step) == 0);
前のはどういう思想だったんだろう? 激しく気になる*1
で、肝心の対処方法は
% sed '3~3a---' eplx.out 77050000 hoge: 000000 77100000 hoge: 000000 84900000 hoge: 000110 --- 84950000 hoge: 000110 86300000 hoge: 000101 86350000 hoge: 000101 --- 87700000 hoge: 000100
でした(最初っからそうせい!)
追記:
ようやく理解した。前のは mod範囲aを指定して、そのうちのオフセット b の位置でマッチ、という考え方だったのか。
なーるほどねえ。それはそれでありか。
*1:単なる馬鹿でしたーだと楽なんだけど