3

How do I search&replace selected instances (in particular those occurring in strings, not in variable names – but using an equivalent of 'query-replace is safer and still fine, there should not be too many hits) of lexibank with lexikudang in all files below a certain directory, keeping capitalization – that is, i.e. also replacing Lexibank with Lexikudang and LEXIBANK with LEXIKUDANG?

1

Switch to the desired directory in dired, and type C-u s R RET t. This should mark all files in that directory, including it's subdirectories. Then enter dired-do-query-replace-regexp with something like

xxx -> \,(if (nth 3 (syntax-ppss)) "yyy" \&)

as regexp -> replacement input.

  • Awesome! It will be also useful to add explanation on how you use syntax-ppss to check of in string and also a link to documentation that gives that info. I think that \& is also not widely known. So adding a line to explain that will be useful too. Also, what is s bound to in dired? People not using dired too frequently (like me) wouldn't know what that does by reading this post. Thanks! – Kaushal Modi Aug 27 '16 at 14:11
  • I am assuming that s R does Recursive select? Then what does the C-u prefix do? I am not at a computer, else would have confirmed. – Kaushal Modi Aug 27 '16 at 14:12
  • 1
    s changes the sort order. It's not useful for that here. But with C-u it instead lets you specify the ls switches to use (in this case, R, for recursively listing, which puts all subdir listings in the same Dired buffer). (You can also change the ls switches by relisting the directory: C-u C-x d.) – Drew Aug 27 '16 at 15:18
1

If the files to search are not in the same Dired buffer (same directory listing or included subdir listings), but are in a directory tree (a directory and its subdirectories, recursively) then you can use command diredp-do-query-replace-regexp-recursive from library Dired+. It is a super version of dired-do-query-replace-regexp (see @politza's answer, and below).

C-h f diredp-do-query-replace-regexp-recursive says:

diredp-do-query-replace-regexp-recursive is an interactive Lisp function in dired+.el.

(diredp-do-query-replace-regexp-recursive FROM TO &optional ARG)

Do query-replace-regexp on marked files, including in marked subdirs. Query-replace FROM with TO.

Like dired-do-query-replace, but act recursively on subdirs. The files included are those that are marked in the current Dired buffer, or all files in the directory if none are marked. Marked subdirectories are handled recursively in the same way.

With an (explicit) numeric prefix argument:

  • >= 0 means ignore all marks - include ALL files in this Dired buffer and all subdirs, recursively.

  • <= 0 means replace only word-delimited matches.

If you exit (C-g, RET or q), you can resume the query replacement using M-,.

In addition, if you use Dired+ then standard command dired-do-query-replace-regexp is also enhanced to perform different behaviors, depending on a prefix argument:

dired-do-query-replace-regexp is an interactive Lisp function in dired+.el.

It is bound to Q, menu-bar operate search query-replace.

(dired-do-query-replace-regexp FROM TO &optional ARG)

Do query-replace-regexp of FROM with TO, on all marked files.

NOTE: A prefix arg for this command acts differently than for other commands, so that you can use it to request word-delimited matches.

With a prefix argument:

  • An odd number of plain C-u: act on the marked files, but replace only word-delimited matches.
  • More than one plain C-u: act on all files, ignoring whether any are marked.
  • Any other prefix arg: Act on the next numeric-prefix files.

So for example:

  • C-u C-u C-u: act on all files, replacing word-delimited matches.
  • C-u 4: act on the next 4 files. C-4 means the same thing.
  • C-u: act on the marked files, replacing word-delimited matches.

If you exit (C-g, RET or q), you can resume the query replace with the command M-,.


To preserve case when replacing, as you requested, ensure that option case-fold-search is non-nil. See the Emacs manual, node Replacement and Case, for more information about this.

0

If you use library Isearch+, including isearch-prop.el then you can use command isearchp-thing or isearchp-thing-regexp to search only within the contexts of strings, by entering string at the prompt for the thing type.

While searching incrementally, you can replace the current search hit using C-M-RET. You can change the replacement text anytime using C-u C-M-RET. And the replacement text can be interpreted as in query-replace-regexp. In the latter case, you can use \&, \=\N, \#, and \,. (C-M-- toggles whether replacement respects these constructs or is literal.)

With Isearch+ you can also limit any incremental search to the active region. So for example, you can search only within strings, and only those strings that are in the active region. You can use C-x n during search to toggle whether the active region restricts search scope.

These commands are only for the current buffer, but with Dired+ you can use M+-F (diredp-do-find-marked-files-recursive) in Dired to open all marked files, including in marked subdirectories.

More information.

0

If you use library Icicles then, similarly to Isearch+, you can search-and-replace incrementally within only strings.

Like Isearch+, you can change the replacement text anytime, and it can make use of query-replace-regexp constructs like \&, \=\N, \#, and \,.

Unlike Isearch+, you can narrow the search contexts incrementally, by typing a pattern to match on the fly. And unlike isearchp-thing(-regexp), you can search multiple files or buffers at the same time.

Search and replacement are each direct-access: you can visit particular search hits selectively, and selectively choose any of them to replace. You can also visit any number of them in sequence, and you can change the sequence sort order (i.e., not just buffer-occurrence order).

See Icicles - Search and Replace for more information.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.