rgrep - Emacsを使ってまだ開いていないテキストファイルを再帰的に見つけて置き換える




emacs rgrep (9)

この質問のフォローアップとして、 このようなやり方を見つけようとしています。これは容易ではないでしょう。特にEmacsの使用に慣れず、既によく知っているエディタを起動するのを止めます。 この例は、複数のファイルを編集する際にかなり頻繁に使用します。

Ultraeditでは、Alt + sを押してからpを押すと、検索(複数行にわたる正規表現の使用を含む)、ファイル/タイプの置換、ディレクトリ、大文字小文字の区別、一括単語のみの一致、リスト変更されたファイルとサブディレクトリの検索。 通常は、まずマウスでクリックしてドラッグし、置き換えるテキストを選択します。

外部ユーティリティを呼び出さずに、Emacs自身(Windows XPの場合のみ)を使用して、foo \ nbarを*.cおよび*.hファイルのbar \ nbazに置き換える方法をいくつかのフォルダとその下にあるすべてのフォルダに置きます。 おそらく、Emacsはこれを行うための最良のツールではないかもしれませんが、どのようにして最小限のコマンドで簡単に行うことができますか?


  1. Mx find-name-dired :ルートディレクトリとファイル名パターンの入力を求められます。
  2. 見つかったすべてのファイルについて、「マークを切り替える」を押す。
  3. Qを押して「ファイル内のクエリ置換」を選択すると、クエリ/置換正規表現の入力を求められます。
  4. query-replace-regexpSPACEを使用して次の一致に置き換えて移動しますnは一致をスキップします。
  5. Cx sを押してバッファを保存します。 ( ynまたは!を押すと一度にすべてを保存できます)

Emacsではありませんが、xxdiffというツールはxx-renameというツールを備えています.xx-renameというツールは、一度に複数の文字列(例えば、From ToからFROM TO)、インタラクティブなプロンプト、すべての変更ファイルのバックアップの保存、コンテキストに加えられた変更のログ。 それは私が大きな/グローバルな名前を変更するときに使う傾向があります。


diredを使って深いディレクトリツリーを再帰的に再利用することは、この作業のために少し遅くなるでしょう。 tags-query-replace使用を検討することもできtags-query-replace 。 これは、タグテーブルを作成するために砲撃することを意味しますが、それはとにかく便利なことが多く、簡単です。


MX Dired 、tはすべてのファイルをマークし、 Qはクエリのすべてのテキストを置き換えます。 クエリ置換の前にiコマンドを使用してサブディレクトリを展開することができます。 私が追加している重要な情報は、iコマンドに接頭辞(control-u)を付けるとargを要求し、-R引数がすべてのsubdirsdiredバッファに再帰的に展開するということです。 これで、ディレクトリ全体のすべてのファイルを検索できるようになりました。


もう一つの選択肢は、 氷床の検索を使用することです。 これは、検索ヒットに対してミニバッファ入力の完了を使用する別の種類の増分検索です。 現在の入力を変更すると、一致するヒットのセットがバッファ*Completions*更新されます。

任意の数のファイル、バッファ、またはブックマークされた場所を検索することができます。ミニバッファパターン(例えばregexp)のマッチングを使用して選択できます。

検索ヒットにアクセスすると、ヒット全体または現在のミニバッファ入力と一致する部分だけをオンデマンドでreplaceことができます。 オンデマンドでの交換は、順番に各検索ヒットについてクエリされないことを意味します。 任意の順序で、直接あなたが望むヒットにアクセスします。 このアプローチは、置換する数が限られている場合はクエリ置換よりも効果的ですy/n徹底的なプロンプトをスキップします。

検索は、あなたが定義した検索コンテキストを超えています。ターゲットファイルのすべてのテキストを検索することに限定されません(たとえば、コメントや特定の種類のプログラムセクションをスキップできます)。 検索コンテキストの簡単な例は、 grepような行ですが、コンテキストは好きなパターンで一致する任意のテキストブロックにすることができます。 通常、正規表現を使用して検索コンテキストを定義しますが、代わりに関数を使用できます。 独自の定義に加えて、異なる種類のコンテキスト(テキストプロパティまたはオーバーレイプロパティのブロック、実際のものなど)にあらかじめ定義されたIcicles検索コマンドがあります。

検索ヒットをさまざまなソート順で並べ替えて、より簡単なアクセス/ナビゲーションを行うこともできます。


オープンバッファの場合、これは私が行うことです:

(defun px-query-replace-in-open-buffers (arg1 arg2)
  "query-replace in all open files"
  (interactive "sRegexp:\nsReplace with:")
  (mapcar
   (lambda (x)
     (find-file x)
     (save-excursion
       (goto-char (point-min))
       (query-replace-regexp arg1 arg2)))
   (delq
    nil
    (mapcar
     (lambda (x)
       (buffer-file-name x))
     (buffer-list)))))

提供される回答は素晴らしいですが、私は少し異なるアプローチを追加すると思いました。

よりインタラクティブな方法であり、 wgreprgrep 、およびieditが必要wgrepieditwgrep両方は、 wgrepまたはMarmalade経由でインストールする必要があります( Mx package-list-packagesを使用)

最初にMx rgrepを実行して、探している文字列を探します。

ファイルタイプ/パターンと再帰するフォルダを指定することができます。

次に、 wgrepCs Cp起動する必要があります。

Wgrepはrgrep結果を編集できるようにするため、文字列の領域を一致させ、 iedit-modeC-;開始しC-; (端末に応じて、これを再バインドする必要があるかもしれません)

すべてのオカレンスは一度に編集可能です。 wgrepをコミットするCx Cs 。 その後、 Cx s ! 変更されたファイルを保存します。

この方法の主な利点は、 iedit-modeを使用して特定の一致を切り替えることができることM-; 。 また、予期しない一致があった場合など、 rgrepの結果をrgrepにジャンプすることもできます。

ソースの編集やシンボル(変数、関数名など)の改名は、プロジェクト全体で非常に便利です。

ieditモードをまだ知っていない/使用していないのであれば、それはとても便利なツールです。私は強くお勧めします。


私はまだ言及されていない、 Helmというもう一つの素晴らしいツールを提案したいと思います。

helm-find-filesは、複数の選択されたファイル内でクエリ置換(regexpを含む)を実行できるようにします。

helm-find-files開いて、 M-SPC関連するファイルをマークし、 F6またはF7を使用して、選択したファイルでクエリ置換またはクエリ置換正規表現を実行します。


  • Mx find-name-dired RET
    • すべてのファイルがリストに表示されるまでに時間がかかることがあります。「 find finished 」が表示されるまで下にスクロールして( M-> )、すべてがロードされていることを確認します
  • 見つかったすべてのファイルに対してtを押して「マークを切り替える」
  • Qを押して「ファイル内のクエリ置換」を選択すると、クエリ/置換正規表現の入力を求められます。
  • query-replace-regexp:SPACEまたはyを使用して次の一致に置換して移動し、nを使用して一致をスキップします。
    • タイプ! 現在のファイル内のすべての出現箇所を尋ねることなく置き換えるには、 Nを押して現在のファイルの残りの部分をすべてスキップします。 ( Nはemacs 23+のみです)
    • これ以上確認せずにすべてのファイルを置換するには、「 Yます。
  • 開いているすべてのファイルを一覧表示するには、 "ibuffer"(ibufferにバインドされている場合はCx Cb 、RxがMx ibuffer RET )をMx ibuffer RETます。
  • * u未保存のファイルをすべてマークするには* uと入力し、マークされたすべてのファイルを保存するにはSと入力します
  • * * RETすべてのマークのマークを解除する場合は* * RET 、マークされたすべてのファイルを閉じる場合はDを入力します

この回答は、 この回答から、 このサイトから、および自分のメモから組み合わせられます。 Emacs 23+を使う。





editor