Skip to content
2月 25 / rakkyoo

複数のファイル内の文字列を一括置換

複数のファイルの文字列を一括置換.なおかつ,サブディレクトリも含めて全部置換したい場合にどうしたらいいのか探していました.

terminal 上で簡単にできるとのこと.

方法としては,

  1. 「find」を使ってサブディレクトリまでファイルをチェック
  2. 「grep」を使ってファイル内の文字列を検索
  3. 「rubyのワンライナー」で一括置換

といった感じでできました.

1.「find」を使ってサブディレクトリまでファイルをチェック

これは,とっても簡単で,たとえばCSVファイルをカレントディレクトリ「.」からサブディレクトリも含めて探したいときは,

1
$ find . -name "*.csv"

こんな感じでOKです.「-name」オプションをつけて,「”*.csv”」を指定すれば,拡張子がcsvのファイルに限定できます.

2.「grep」を使ってファイル内の文字列を検索


findの結果をgrepに渡して,検索します.文字列「test」を検索したいときは,

1
$ find . -name "*.csv" | xargs grep test

これだけでできます.
ちなみに,findの結果をgrepに渡すのには,「xargs」を使いました.xargsは,コマンドに引数として,標準入力の内容を渡したいときに使うコマンドなので,とっても便利です.
検索結果が出力されるので,チェックをして,,,

3.「rubyのワンライナー」で一括置換


grepで抽出したファイルをrubyのワンライナーに渡して,一括置換します.
このときに,grepに「-l」オプションをつけると,抽出ファイルのパスだけが出力されるので,「-l」オプションをつけて,rubyのワンライナーに渡します.
rubyのワンライナーは,とっても簡単で,今回使うのは以下のオプションくらいです.

    -e コマンドラインからスクリプトを指定
    -i ファイルを上書き
    -p 各行ごとに処理して出力
    -n 各行ごとに処理

今回やりたいことでは,「-e」「-i」と「-p」または「-n」を使えばできます.
pかnは出力するかどうかなので,どっちでも大丈夫です.
rubyのスクリプトとしては,置換するのに「gsub」を使えばいいだけです.上書きしてしまうので,破壊的メソッドで「gsub!」とすればOKです.「test」を「tttt」に変換するのであれば,

1
gsub!(/test/,"tttt")

こんな感じかなと.これをワンライナーにすればいいだけなので,

1
$ find . -name "*.csv" | xargs grep -l test | ruby -i -ep 'gsub!(/test/,"tttt")'

これで終了です.

上書きが怖ければ,「-i.bak」にして,バックアップファイルを作ってもOKです.

1
$ find . -name "*.csv" | xargs grep -l test | ruby -i.bak -ep 'gsub!(/test/,"tttt")'

作ったバックアップファイルを消去したければ,今回の例では,

1
$ find . -name "*.csv.bak" | xargs rm

とすれば全部消えます.
特にソフトとかが必要ないところがlinux系OSだといいですね.

[`twib` not found]

Leave a comment

CAPTCHA


This blog is kept spam free by WP-SpamFree.