web-dev-qa-db-ja.com

vimで検索してackで置き換える方法は?

私はVimでAckプラグインを使用しています。これは、プロジェクトで文字列をすばやく検索するのに役立ちます。ただし、見つかった文字列のすべてまたは一部を置換したい場合があります。次のようなVim arglistを使用して、なんらかのグローバル検索と置換を行うことができます( source ):

:args app/views/*/*
:argdo %s/, :expire.*)/)/ge | update

しかし、argsを使用する代わりに、Ackを使用して検索を実行してから、見つかったすべてのファイルで置換を実行します。 argdoコマンドに似た方法はありますか?

53

GNUサブセットの代わりに、より強力なPerl正規表現を使用できるように、Vimの外部でこの問題を解決するためにackとPerlを使用することにしました。これをvimrcのキーストロークにマッピングできます。

ack -l 'pattern' | xargs Perl -pi -E 's/pattern/replacement/g'

説明

ack

ack は、grepfind、および完全なPerl正規表現(GNUサブセットだけでなく)を組み合わせた素晴らしいコマンドラインツールです。 )。純粋なPerlで記述され、高速で、一致の強調表示があり、Windowsで動作し、従来のコマンドラインツールよりもプログラマーにとって使いやすいです。 Sudo apt-get install ack-grepを使用してUbuntuにインストールします。

xargs

Xargs は古いUNIXコマンドラインツールです。標準入力から項目を読み取り、指定されたコマンドを実行してから、標準入力で読み取った項目を実行します。したがって、基本的に、ackによって生成されたファイルのリストは、Perl -pi -E 's/pattern/replacemnt/g'コマンドの最後に追加されます。

Perl -pi

Perlはプログラミング言語です。 -pオプションを指定すると、Perlはプログラムの周りにループを作成し、ファイル名引数を繰り返し処理します。 -iオプションを指定すると、Perlはファイルを適切に編集します。これを変更してバックアップを作成できます。 -Eオプションを指定すると、Perlはプログラムとして指定された1行のコードを実行します。私たちの場合、プログラムはPerlの正規表現による置換にすぎません。 Perlコマンドラインオプションの詳細については、 perldoc perlrun を参照してください。 Perlの詳細については、 http://www.Perl.org/ を参照してください。

93
Eric Johnson

現在、Vimにはこの新しいコマンドcdoがあり、クイックフィックスリストの各行に対して指定されたコマンドを実行します。

だからあなたは使うことができます

:Ack pattern
:cdo s/pattern/newpattern/g
34
rools

これを行う方法が組み込まれているとは思いませんが、簡単に作成できるはずです。

必要なことは、カスタム関数を呼び出すコマンドを作成することです。次に、関数はgetqflist()関数を使用してクイックフィックスリストのすべてのエントリを取得し、exeを使用してダーティな作業を行う必要があります。引数として渡すものに注意してください!

" Define a command to make it easier to use
command! -nargs=+ QFDo call QFDo(<q-args>)

" Function that does the work
function! QFDo(command)
    " Create a dictionary so that we can
    " get the list of buffers rather than the
    " list of lines in buffers (easy way
    " to get unique entries)
    let buffer_numbers = {}
    " For each entry, use the buffer number as 
    " a dictionary key (won't get repeats)
    for fixlist_entry in getqflist()
        let buffer_numbers[fixlist_entry['bufnr']] = 1
    endfor
    " Make it into a list as it seems cleaner
    let buffer_number_list = keys(buffer_numbers)

    " For each buffer
    for num in buffer_number_list
        " Select the buffer
        exe 'buffer' num
        " Run the command that's passed as an argument
        exe a:command
        " Save if necessary
        update
    endfor
endfunction
16
DrAl

この方法でackを使用できます

:args `ack -l User app/`
:argdo %s/, :expire.*)/)/ge | update

またはagを使用

:args `ag -l User app/`
:argdo %s/, :expire.*)/)/gec | w
10
Ilake Chang

MacVimを使用しています(シェルではmvimでアクティブ化)。 ackの結果をmvimにパイプします。

mvim -f $(ack -l $@)

次に、MacVimでbufdoを使用して検索/置換します。

:bufdo %s/SEARCH/REPLACE/gce | update

確認が不要な場合は、cオプションを省略します。

9
milkfarm