作曲・指導・C言語・Linux

金沢音楽制作

金沢音楽制作では、楽曲・楽譜の制作と、作曲や写譜などレッスンを行っています。

複数のファイルの内容を一括で置換する

sed-iオプションを使って破壊的な置換を行います。ファイルの対象や構造を完全に理解していない場合は非推奨ですので、自己責任の上で実行してください。


ディレクトリ配下にある、大量のファイルの内容を一括で置換する方法についてのメモです。grepsedの2つのコマンドを使用します。なお、sedで用いる-iオプションは、GNUのsedのオプションです。したがって、macOSといったBSD環境の場合は、別の工夫が必要になります。

本稿では、htmlに記述されている外部CSSのファイル名を変更するケースを取り扱います。具体的には、<link href="~/css/main_0320.css" rel="stylesheet"><link href="~/css/main_0401.css" rel="stylesheet">と、付された数字(月日)を変更します。

ディレクトリ構造は次の通りです。この中のhtmlファイル、~/index.html~/blog/index.html、そして~/blog/2020/n{101..103}.htmlが対象です。

$ tree
|--- blog
|    |--- 2020
|    |    |--- n101.html
|    |    |--- n102.html
|    |    `--- n103.html
|    `--- index.html
|--- css 
|    |--- main_0320.css
|    `--- sub.css
`--- index.html

環境:grep (GNU) 3.4、sed (GNU) 4.8

コマンド例

次のコマンドで、ディレクトリ配下のファイルの内容を一括で置換できます。繰り返しになりますが、対象のファイルを直接操作する破壊的な置換になります。

$ grep -rl 'main.*css' . | xargs sed -i 's/0320/0401/'

grepで処理対象のファイル名を取得し、xargssedの引数にgrepで取得したファイル名を渡していす。

このコマンドが一体何をしているのか、詳しく見ていきましょう。

grepで対象ファイル名を表示する

grepを使って、置換対象となるファイル名の一覧を取得します。

まず、grepで置換対象となるcssのリンクが書かれたhtmlファイルを探します。階層型のディレクトリですから、-rオプションを付けて、再帰的な検索を可能にします。また、-oオプションを付けて、マッチしたファイル名と文字列のみを表示して結果を見やすくします。最後に任意の検索の開始ディレクトリを指定します。今回は、カレントディレクトリ配下を検索したいので、.*をつけます。

実行すると、マッチした内容が表示されました。これで問題ないか確認します。

$ grep -ro 'main.*css' .
blog/2020/n101.html:main_0320.css
blog/2020/n102.html:main_0320.css
blog/2020/n103.html:main_0320.css
blog/index.html:main_0320.css
index.html:main_0320.css

問題がなければ、-lオプションを付けてファイル名を表示します。ちなみに、-rolと書いても同じ結果になります。

$ grep -rl 'main.*css' .
blog/2020/n101.html
blog/2020/n102.html
blog/2020/n103.html
blog/index.html:mai
index.html

sedの引数にgrepの結果を渡す

sedの引数にgrepの結果(ファイル名)をxargsを使って渡します。

$ grep -rl 'main.*css' . | xargs sed 's/main_0320/main_0401/'

実行すると、置換されたファイルの内容が表示されます。内容を確認して問題がなければ、sed-iオプションを付けで実行すると置換されます。

$ grep -rl 'main.*css' . | xargs sed -i 's/main_0320/main_0401/'

更新情報

  • 作成日:2020-03-23
  • 更新日:2022-04-28