LoginSignup
7
3

More than 5 years have passed since last update.

Gitレポジトリ内の文字列を一括置換する git-sed

Posted at

近頃のIDEや高級エディタでは、プロジェクトの全ファイルから文字列を検索して一括置換できるものが多いのですが、残念ながら一括置換が無かったり、IDEを起動するのが面倒だったり、そもそもIDEを使えないこともあります。

そこで、CLIで全ファイル一括置換する方法をご紹介します。

git ls-files を使えばよい

レポジトリ内の全ファイルをリストアップできます。

$ git ls-files --help
NAME
       git-ls-files - Show information about files in the index and the working tree

SYNOPSIS
       git ls-files [-z] [-t] [-v]
                       (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])*
                       (-[c|d|o|i|s|u|k|m])*
                       [--eol]
                       [-x <pattern>|--exclude=<pattern>]
                       [-X <file>|--exclude-from=<file>]
                       [--exclude-per-directory=<file>]
                       [--exclude-standard]
                       [--error-unmatch] [--with-tree=<tree-ish>]
                       [--full-name] [--recurse-submodules]
                       [--abbrev] [--] [<file>...]
(以下略)

なので、sed コマンドなどの編集コマンドとつなげば一括置換は簡単です。

$ git ls-files | xargs -L 1 sed -e 's/before_filter/before_action/g' -i

$ git ls-files | while read -r f; do sed -e 's/before_filter/before_action/g' -i "$f"; done

コマンドにしてみた(git-sed)

毎回パイプやwhileを書くのが面倒なので、コマンドにしてみました。

git sed 's/before_filter/before_action/g' で使えます。

#!/bin/bash
set -euC
if [ "$#" -eq 0 ]; then
  echo 'git sed [SED-COMMANDS]' >&2
  exit 1
fi

if which gsed > /dev/null; then
  SED=gsed
else
  SED=sed
fi

cmd=()
while [ "$#" != "0" ]; do
  cmd+=(-e "$1")
  shift
done

git ls-files | while read -r f; do
  # シンボリックリンクにはsedを適用しない(リンクを一度削除して、通常のファイルとして作り直してしまうため)
  [ -f "$f" ] && [ ! -L "$f" ] && "$SED" -i "${cmd[@]}" "$f"
done
7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3