Vim検索は、現在の(プロジェクト)フォルダー内のすべてのファイルを置き換えます


36

Vimについての未解決の質問の1つは、現在のプロジェクトで検索/置換を実行する方法があるかどうかです(他のエディターから継承されたこの概念を使用する場合はご容赦ください)。

たとえば、プロジェクトファイルでメソッド名を検索し、そのメソッド呼び出しのすべてのインスタンスの名前を変更したいとします。

これがSublimeの進め方です。

ここに画像の説明を入力してください

ackまたはなどの他のプログラムに依存せずに、Vim(おそらくMacVim)でこれをどのように行いますかsed

回答:


35

これを行うにはいくつかの方法があります。

現在のディレクトリ内

プロジェクトツリーで検索/置換を実行する場合は、Vimの引数リストを使用できます。

Vimを開き、:argsコマンドを使用して引数リストを作成します。複数のファイル名またはグロブさえ渡すことができます。

たとえば:args **/*.rb、現在のディレクトリで再帰的にrubyファイルを検索します。これは、でVimを開くようなものvim **/*.rbです。シェルのfindコマンドを使用して、現在のディレクトリ内のすべてのファイルのリストを取得することもできます:

:args `find . -type f`

:args単独で実行することにより、現在の引数リストを表示できます。リストからファイルを追加または削除する場合は、:argaddまたは:argdeleteコマンドをそれぞれ使用できます。

リストに満足したら:argdo、引数リスト内のすべてのファイルに対してコマンドを実行するVimの強力なコマンドを使用できます。:argdo %s/search/replace/g

検索のヒントをいくつか紹介します(いくつかのコメントに基づく):

  1. 「foo_bar」ではなく「foo」を検索する場合は、単語境界を使用します。次のように、検索パターンを囲むように\<and \>構造を使用します。:argdo %s/\<search\>/foobar/g
  2. /c検索用語を置換する前にVimに確認を求める場合は、検索フラグを使用します。
  3. /e「パターンが見つかりません」エラーをスキップする場合は、検索フラグを使用します。
  4. 検索の実行後にファイルを保存することもできます:argdo %s/search/replace/g | update:update変更された場合にのみファイルを保存するため、ここで使用されます。

オープンバッファ

検索/置換を実行するバッファを既に開いている場合は、を使用:bufdoして、バッファリストのすべてのファイルに対してコマンドを実行できます(:ls)。

コマンドは非常に似てい:argdoます: :bufdo %s/search/replace/g

同様に:argdoして:bufdo、そこにある:windo:tabdo、それぞれのウィンドウとタブ上の行為。あまり使用されませんが、知っておくと便利です。


4
/cフラグを使用して置換を確認することをお勧めします。
ロメインル

3
また、部分的な単語の置き換えを避けるために、単語の境界\<を使用することをお勧めします。\>search
-tommcdo

1
もう1つのコメントは、vimの作業ディレクトリはデフォルトでvimを起動した場所であり、現在のファイルのディレクトリではないということです。を使用して、作業ディレクトリを現在のファイルに設定できます:cd %:p:h。その他の作業ディレクトリオプションは、vim.wikia.com / wiki / Set_working_directory_to_the_current_fileにリストされています
スタッドギーク

29

次のような単純なプロジェクト構造があるとします。

ここに画像の説明を入力してください

greeting.txtは次のようになります

ここに画像の説明を入力してください

info / age.txtは次のようになります

ここに画像の説明を入力してください

Samのすべての出現をBobに置き換えたいとします。ここに私たちがやることがあります:

  1. 作業ディレクトリを設定する

    Vimの現在の作業ディレクトリがプロジェクトのルートであることを確認してください(ここでこれを行う方法は説明しません)。

  2. 「サム」を含むファイルを検索する

    Vimのvimgrepコマンドを使用して、プロジェクト内で発生するすべてのSamを検索します(注:**/*すべてのファイルを再帰的に検索します)

    :vimgrep /Sam/gj **/*
    

    これにより、クイックフィックスリストにSamのすべてのインスタンスが入力されます。クイックフィックスリストを表示する場合は、Vimコマンドを使用できます:copen ここに画像の説明を入力してください

  3. 「Sam」を含むすべてのファイル内で置換

    ここで、クイックフィックスリストのすべてのファイル内でVimの代替コマンドを実行します。これ:cfdo {cmd}は、クイックフィックスリストの各ファイルで{cmd}を実行するコマンドを使用して実行できます。私たちが使用する特定の{cmdは}であるsubstituteか、s略し。完全な行は次のようになります。

    :cfdo %s/Sam/Bob/g
    

    必要に応じて、cフラグを追加してすべての置換を確認できます。

    :cfdo %s/Sam/Bob/gc
    
  4. すべてのファイルを保存する

    :cfdo update
    

2
これがもっと好きです。シンプルで、Ack(またはQuickFixウィンドウに入力するプラグイン)で動作します。
ズハイブ

1
これは素晴らしい答えです
Peoplee

2
「最後の変更以来、何の書き込み」を取得しなかった、やってcfdo %s/Sam/Bob/g | update固定している私のために
hakunin

@hakuninまだ設定していない場合は、hiddenオプションを設定することをお勧めします:set hidden
ニコBellic

3

VIMソリューションではありませんが、VI / VIMを使用している場合は、CLIソリューションを使用する方が簡単な場合があります。現在のディレクトリ内のすべてのファイルを変更perlするには、次のような状況で作成されたとおりに使用します。

$ perl -pi -e 's/foo/bar/g' *

あなたもサブディレクトリでそれを行う必要がある場合、私は通常とペアにperlなりfindます:

$ find . -name '*' -print0 | xargs -0 perl -pi -e 's/foo/bar/g'

これの良い点は、リストを特定のファイルタイプに簡単にさらに絞り込むことができることです。たとえば、Pythonファイルに制限するには:

$ perl -pi -e 's/foo/bar/g' *.py
$ find . -name '*.py' -print0 | xargs -0 perl -pi -e 's/foo/bar/g'

1

フレーズを別のフレーズに置き換えるには、Vim Exモードを使用できます。

例(exはのエイリアスvim -E):

$ ex -s +'bufdo!%s/foo/bar/g' -cxa *.*

bash / zshで再帰的に(globstarセットなどでshopt -s globstar):

$ ex -s +'bufdo!%s/foo/bar/g' -cxa **/*.*
$ ex -s +'n **/*.*' +'bufdo!%s/foo/bar/g' -cxa

再帰的に(findファイルなどの隠しファイルを使用および無視.git):

$ find . -type f -not -path '*/\.*' -exec ex -s +'bufdo!%s/foo/bar/g' -cxa {} "+"

注::bufdoコマンドはPOSIXではありません。

注:構文-not -path '*/\.*'は、隠しファイル(など.git)を無視するために使用されます。



0

次に、findand ex使用した:bufdo(を使用しない)シェルコマンドを示します。

find . -name '*.rb' -exec ex +'%s/foo/bar/ge' -V1 -scwq! {} ';'

これ*.rbにより、現在のフォルダー内のすべてのファイルが(再帰的に)その場で編集され、に置き換えfooられbarます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.