指定した複数の行番号に対する文字列処理
sed のアドレス指定は1行の指定や開始行と終了行による範囲指定くらいしかなく,任意の複数行の指定ができない.
そこで,以下のように,単純に行ごとにコマンドを繰り返して sed に流し込んでみた.
$ (for i in `cat LINES`; do echo "${i}SED_COMMANDS"; done) | sed -f - TEXTFILE
この方法は LINES や TEXTFILE が大きくなると劇的に遅くなる.生成する sed スクリプトが肥大化するのはもちろんだが,恐らく sed の内部処理的に TEXTFILE を毎回走査するとかいうアホなことになっているのだろう.もっとうまい方法はないだろうか?
ただ,もし LINES が seq の INCREMENT 指定で生成できるような単純な飛び飛びの値だった場合,GNU 版 sed のアドレス指定 n~s (n 行目から s 行ごと) を使って少し工夫すれば圧倒的に速くなる.
$ seq 1 50000 > a.txt $ time (for i in `seq 1 2 10000`; do echo "${i}s/^/# /"; done) | sed -f - a.txt > b.txt real 0m11.718s user 0m10.424s sys 0m0.130s $ time (head -10000 a.txt | sed '1~2s/^/# /'; sed -n '1,10000!p' a.txt) | cat - > c.txt real 0m0.636s user 0m0.340s sys 0m0.160s $ diff b.txt c.txt $