macro to find/replace in current directory?
-
I coccasionally have to replace all e-mail addresses in a couple of XML files in varying folders with a defined value. Unfortunately “any e-mail address” is not a trivial regex and I can’t force the value to stay put in the list of recently-used searches. It just fades away quickly and I have to supply it again from “elsewhere”.
I know how to find/replace content in a folder an possibly sub folders and I know how to use the “folder of current file” within the search/replace dialog.
However I get nowhere when trying to automate this repetitive task, possibly by means of a macro or similar.
I was able to make a macro to do the replace within the current document in %appdata%\Notepad++\shortcuts.xml
like this:
<Macro name="Replace E-Mail addresses" Ctrl="yes" Alt="no" Shift="yes" Key="69"> <Action type="3" message="1700" wParam="0" lParam="0" sParam="" /> <Action type="3" message="1601" wParam="0" lParam="0" sParam=">(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}\b)<" /> <Action type="3" message="1625" wParam="0" lParam="2" sParam="" /> <Action type="3" message="1602" wParam="0" lParam="0" sParam=">me@work.com<" /> <Action type="3" message="1702" wParam="0" lParam="768" sParam="" /> <Action type="3" message="1701" wParam="0" lParam="1609" sParam="" /> </Macro>
But if I try this with the replace in files dialog, I just fail on the part to get “the current directory” into the macro. It works if I put a defined folder there, but I want the “folder of the currently opened file” to be used:
<Macro name="Replace all E-Mail Addresses in current Dir" Ctrl="yes" Alt="yes" Shift="yes" Key="69"> <Action type="3" message="1700" wParam="0" lParam="0" sParam="" /> <Action type="3" message="1601" wParam="0" lParam="0" sParam=">(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}\b)<" /> <Action type="3" message="1625" wParam="0" lParam="2" sParam="" /> <Action type="3" message="1602" wParam="0" lParam="0" sParam=">me@work.com<" /> <Action type="3" message="1653" wParam="0" lParam="0" sParam="$(CURRENT_DIRECTORY)" /> <Action type="3" message="1652" wParam="0" lParam="0" sParam="*.xml" /> <Action type="3" message="1702" wParam="0" lParam="96" sParam="" /> <Action type="3" message="1701" wParam="0" lParam="1660" sParam="" /> </Macro>
Any Ideas how to solve this task?
-
I understand the frustration here. :-(
A similar problem to yours is wanting to have a macro that uses selected data (or even clipboard data) as part of the regex; to mock up an example of something like this would be:
\b[A-Za-z0-9._%+-]$(CURRENT_WORD)+@[A-Za-z0-9.-]+.
Or to get even more fanciful:
\b[A-Za-z0-9._%+-]$(CLIPBOARD)+@[A-Za-z0-9.-]+.
Alas, neither of these work (as you know); a macro for search/replace is currently always VERY hard-rooted in fixed data.
There seem to be two things you desire, on an either-or basis:
-
easy recall of your regular expression
-
the macro not being so “hard-rooted”
Here’s a technique I use to solve the “easy recall” part; I’ll show it in an example of how I use it.
We frequently see requests posted here for "how do I find/replace a certain piece of text, but only when it occurs between two other (specified) pieces of text. We have a solution for that, and I go and dig up the link to the solution and paste it into my reply.
OR… I run a macro I have that does a Find All in Current Document (after this: FACD) search, which then outputs this in my Search results window:
Note that I now have quick access to copy the link I need to post, plus I also have the regex recalled if I want to copy that to experiment with a poster’s exact text-and-delimiters replacement scenario. (The fact that my search had zero hits is irrelevant as I’m just using this for “easy recall” of some text).
So my suggestion for you (@rorso) is to record your regex search in FACD form into a macro. Then, when you have a file open in a folder that needs your intended replacement, start doing a Find in Files to get the Directory box configured correctly (presumes Follow current doc. checked as that’s the smart play!). Then run the macro, and copy the regex text from the Search results window over to the Find in Files’s Find what box. If your Replace with expression is complicated, you can also include it in the macro, perhaps as a regex “comment”
(?#...)
like I did for my link text (downside: requires a 2nd copy+paste). Finally, you press the Replace in Files button…Having such a macro run as a FACD has an additional benefit: It will show you matches for your current file, giving you more confidence that you are about to “do the right thing” when you Replace in Files.
I can’t force the value to stay put in the list of recently-used searches. It just fades away quickly and I have to supply it again from “elsewhere”.
Admittedly, my technique also requires supplying the regex from “elsewhere”. But at least this elsewhere can be a fixed place in the macro menu (providing fairly easy and quick access).
Is my technique ideal? Absolutely not.
Does it really suck? Maybe.
It’s a macro-based “solution”, just not the one you really wanted. :-(It may depend on how often you do your operation; obviously my “link recall” thing is not something I need to do with high frequency.
-
-
@Alan-Kilborn
Thanks for your Idea. You are right, it is somehow - er - indirect. But it obviously does the job, so It’s what I call a usable solution. I will do the same.I meanwhile have a Plan-B without NP++ at all, utilizing PowerShell and a link in “send to” to mark and process an arbitary set of files from the Windows-Explorer, but I definitely keep this solution.
Problem solved.
:-) -
Cool that that technique can work for you. I had another idea which as “heavier” as it involved using a scripting plugin, so if that wouldn’t work out for you, I’d’ve gone down that road.