no-image

sed でスクリプトの 1 行目だけを置換える

$ sed '1c 置換え後の内容'

find と組合せて、拡張子が .cgi であるファイルの 1 行目を置換えるには次のようにします。

$ find *.py | xargs sed -i '1c #!/usr/local/bin/python'

未だに時代の流れに乗らずに CGI を書いています。ちょっとした小物を作るときにはお手軽で便利なので、だらだらとこのスタイルを続けています。

今回はその小物たちの #! から始まる一行目、いわゆる shebang を大量に置換える必要が出てきたときのお話です。ある特殊な環境で運用する必要があり、インタプリタの場所が異っていたがために発生した状況です。

一つ一つ書き換えてもそこまで時間がかかるわけではありませんが、プログラマとしてそれはちょっと……となったので調べてみました。

Linux では定番の sed で出来そうです。置換えと行指定を組合せると次のようになります。

$ sed -i '1c #!/usr/local/bin/python' foo.py

これで foo.py の 1 行目が #!/usr/local/bin/python に置替えられます。1 が行、c が丸ごと置替えの指定です。-i オプションはファイルを直接操作するもので、指定しないと標準出力に結果が出力されます。-i.bak (間にスペースなし。付加する拡張子) とすれば操作前のファイルを残してくれます。

これだと単一ファイルの処理しか行えないので、find と xargs を組合せて特定の拡張子のファイルを一括処理してみます。

$ find *.py | xargs sed -i '1c #!/usr/local/bin/python'

これで拡張子が .py であるファイルの 1 行目を全て #!/usr/local/bin/python に置換えることができました。

ディレクトリ以下を再帰的に処理(2018-12-08 追記)

find dir -name FILENAME の形にすればよい。

find ./ -name \*.cgi | xargs find *.py | xargs sed -i '1c #!/usr/bin/python'

参考