58

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

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

ただし、を使用する代わりに、argsAckを介して検索を実行してから、見つかったすべてのファイルで置換を実行することをお勧めします。argdoコマンドと同じようにそれを行う方法はありますか?

4

5 に答える 5

98

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

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

説明

ack

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

xargs

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

perl -pi -E

Perl はプログラミング言語です。

この-pオプションにより、Perl はファイル名の引数を反復するプログラムの周りにループを作成します。

この-iオプションにより、Perl はその場でファイルを編集します。これを変更してバックアップを作成できます。

この-Eオプションにより、Perl はプログラムとして指定された 1 行のコードを実行します。私たちの場合、プログラムは単なる Perl 正規表現置換です。

Perl コマンド ライン オプションの詳細については、 を参照してくださいperldoc perlrun。Perl の詳細については、http://www.perl.org/を参照してください。

于 2012-01-05T14:28:22.913 に答える
50

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

だから、あなたが使用することができます

:Ack pattern
:cdo s/pattern/newpattern/g
于 2016-08-24T09:15:55.073 に答える
16

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

カスタム関数を呼び出すコマンドを作成する必要があります。関数は、その関数を使用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
于 2011-01-25T12:12:27.557 に答える
10

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

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

または ag を使用

:args `ag -l User app/`
:argdo %s/, :expire.*)/)/gec | w
于 2013-03-31T12:56:31.823 に答える
9

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

mvim -f $(ack -l $@)

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

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

c確認が不要な場合はオプションを省略してください。

于 2012-04-25T19:24:22.650 に答える