Find and Replace

I have a web page that uses many small html files within a folder.

I would like to create a macro that will search through all of the files within that folder and change the text.

Example:

Search for the word Contents and change to Introduction

Is this possible in Keyboard Maestro? If so can you get me started. Maybe with a regex that will do it?

Thanks Roger

Give this a shot. Obviously, don't try it on any important data that isn't backed up until you're satisfied with it.

Search and Replace All Files in Folder.kmmacros (22 KB)

Macro screenshot

The only thing I'm not sure about is the format for writing the file at the end as I don't do web design... is plain text okay?

1 Like

As well as @noisneil's KM answer, I'll add a shout out to BBEdit and its multi-file Search and Replace -- available in the free version too.

Other text editors, eg Atom (soon to be sunset, unfortunately), can also do this, often under "Search and Replace in Project" or similar.

1 Like

Nige

Yes BBEdit works great and it what I am now using but I have to run it several times to get what I want.

I was hoping that I create a KB macro that would do it with one click. I'm kinda lazy and always misspell something.

Roger

noisneil

I think my description initially did not explain enough. My top folder named Test has several sub folders and with in those directories there are multi files. It seems that this gets all of the files within the parent folder but not in the sub folders.

Any suggestions?

Screen Shot 2022-08-30 at 12.56.06 PM

@Nige_S helped me with a recursive file renaming script once-upon-a-time and the script part went a little over my head. He's far more qualified with that sort of thing, so this is kinda where I check out... Here's an attempt to do search and replace in one extra layer of subfolders, but it will never be as efficient as a shell script:

Search and Replace All Files in Folder.kmmacros (25 KB)

Macro screenshot

1 Like

"For Each...items in a directory" actually has a "recursively" option (which I probably didn't realise last time!). Makes things a lot easier than anything I might have suggested...

In which case, we'll duplicate the target folder first so it'll be easy to go back to the originals! I've also limited the operation to files ending in ".html" so we don't try editing images or something -- you could change that, or add an "or .css" with another condition, etc. It currently works by asking you to pick the folder to process, but can be easily changed so that you select a folder in the Finder than trigger with a hotkey or palette button.

Roger S'n'R.kmmacros (6.7 KB)

Image

2 Likes

Wow! That's a great find!! :clap:t3::clap:t3:

Thanks for all of the help. Nige that worked perfect. I think that should be placed in the Macro Library.

I am constantly amazed at the willingness of those on this board to share and help others. I hope some day I am smart enough to be of help to others.

Roger

2 Likes

@Nige_S It is WAY too early to have my mind blown like that. :sweat_smile:
That's incredibly useful and I'm shamed and embarrassed that I never spotted it before. :laughing:

This is without a doubt the best forum i've ever been a part of. No doubt you can contribute more than you think even now. :wink:

2 Likes

@RogerW (and tagging @noisneil and @cdthomer)...

Just to add -- "recursively" works here because we are renaming files but not folders. If you want to do folders you'd have to create your recursion manually.

That's because folder renaming requires "depth first recursion", which the action's "recursively" isn't. So a folder would get renamed but then the path to the original name is no longer valid so the folder's contents aren't processed.

In a depth first recursion you'd look in a folder for folders, then look in the first of those for more folders, until no folder is found -- then you rename everything "on the way back up".

4 Likes

This should be added to the wiki! :+1:t3:

1 Like

Makes complete sense, thanks for the info!

I have been using the macro for several weeks and I have one problem.

I have a file that has about 30,000 html records that need to be searched and replaced. I change 3 items so I have to run the macro 3 times. The first 2 passes only change a few of the 30,000 records but the last one changes almost all of them.

When I run the last pass it starts then the finder goes wild and starts. With both of these competing for resources it takes a long time. In fact I will stop the macro and restart it after the finder reduces the amount of resources it needs.

I run the same 3 updates using BBEdit with no problems with any of the 3 and finder dose not kick in and try to take over.

Any suggestions?
Roger

While I'm loving playing with KM, it isn't always the best tool for the job. In this case it looks like BBEdit is much more suited to what you are doing, so my suggestion would be to take advantage of its highly optimised text- and file-processing routines!

BBEdit itself is highly scriptable so there would be few problems running a KM macro that integrated other things and passed off the text editing to BBEdit. Best of both worlds... (and without having to delve into shell scripting!).

I'd also wonder about having to change so many files on even a semi-regular basis. How are they generated, what's "wrong" in that process that you have to revisit them, if it's a regular change on otherwise static data can you replace the hard-coding with server side includes or JavaScript rewrites, etc? This may be a problem better solved "upstream".

2 Likes

Thanks - I think your suggestion to use BBEdit and KM together is something I had not thought of and I will give it a try.

Yes updating that many files is a pain but they are created by another application that I have no control over.

Roger

Here's a macro that does the same as my previous, but using BBEdit to do the S'n'R:

Roger S'n'R with BBEdit.kmmacros (3.8 KB)

Image

You can make the options as complicated as you need -- you can see this one saves every changed file automatically (saving yes) and recurses folders (with recursion) only looking at text files (text files only) whose names end with ".html" (filter:{filter_terms:{field:file_name, operator:op_ends_with, operand:".html"}}). It respects case (case sensitive:true) and doesn't pop BBEdit's "Results" window (showing results:false), though it'll display a notification telling you how many files were changed.

2 Likes

You can change the macro to do 3 search/replace actions serially in the same macro you know.

This is strange and improper.

It's not surprising that BBEdit would do this job better than Keyboard Maestro – it's optimized for that kind of work. It is strange that the Finder would get involved when the KM macro is run...

-Chris

Nice

Thanks for the new macro. I gave it a quick try and it asked for permission to use BBEdit and I replied Yes. Then it quickly gave a message showing the search and replace values and that it changed one file then quit.

In looking at the information I could not find the one file it changed and all of the files I looked at it did not not change work?

Roger

Roger

Good job the macro duplicates the folder first! Reset the files by going back to the old folder version and change the AppleScript action so that showing results:false is showing results:true -- that'll pop the standard BBEdit multi-find results window at the end so you can see which file is changed and compare that to whatever isn't.

What are your search and replace strings? Are you doing plain text or a regex (which might need some cleverness to get through KM and AS's own text processing)?