あるファイルの特定の行を別のファイルの内容に置換する

今日、「↑みたいなことをやりたいんだけど、どうすればいい」と聞かれたので、やってみた。
具体的には以下のようなtestというファイルがあり、

...
test
...
test
...

上記のtestという文字列だけからなる行を以下のtest.inで置換する。

1
2
3
4
5

とりあえず、シェルスクリプトでやってみる。

#!/bin/sh

# test.sh

pattern=$1

while read line
do
   if [ "$1" = "$line" ] ;
   then
       cat test.in
   else
       echo $line
   fi
done
$ ./test.sh test < test
...
1
2
3
4
5
...
1
2
3
4
5
...

$

これでいいじゃんと思ったのだが、「もっと簡単にできない?」とか「ファイルを実行したくない」とかおっしゃられるので、Perlワンライナーで書いてみた。

$ perl -wnl -e 'open(IN, "test.in");local $/ = undef;my
$data=<IN>;chop($data);close(IN); s/test/$data/;print $_;' test
...
1
2
3
4
5
...
1
2
3
4
5
...

$

かえって複雑になってしまったので、とりあえず前者の方を薦めておいた。そのままだとechoされる行にバックスラッシュが含まれている場合、うまくいかないが。