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
?
4 Answers
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 iss
bound to indired
? People not using dired too frequently (like me) wouldn't know what that does by reading this post. Thanks! Aug 27, 2016 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. Aug 27, 2016 at 14:12 -
1
s
changes the sort order. It's not useful for that here. But withC-u
it instead lets you specify thels
switches to use (in this case,R
, for recursively listing, which puts all subdir listings in the same Dired buffer). (You can also change thels
switches by relisting the directory:C-u C-x d
.)– DrewAug 27, 2016 at 15:18
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 indired+.el
.
(diredp-do-query-replace-regexp-recursive FROM TO &optional ARG)
Do
query-replace-regexp
on marked files, including in marked subdirs. Query-replaceFROM
withTO
.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
orq
), you can resume the query replacement usingM-,
.
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 indired+.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
ofFROM
withTO
, 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
orq
), you can resume the query replace with the commandM-,
.
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.
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.
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.