Find and Replace in multiple documents?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
anime
Posts: 5
Joined: 11 Dec 2017, 09:57

Find and Replace in multiple documents?

11 Dec 2017, 10:21

I apologize, I know this has probably been asked, and I can't find it, and I'm in a crazy rush doing about a week's worth of things by tomorrow, so I beg forgiveness.

I have an AHK file that when I'm running it, changes US spelling to UK spelling as I type... Like the autocorrect file, just different (obviously)...

I need to know if I can run this on an already typed out .txt file, and if so, how?

For example, if I have a folder with the files, can I create a batch file or run something from the command prompt that will search/replace words in all of the files with my US to UK library, and maybe even save them from "filename.txt" to "filenameConvert.txt"... although that last part is not necessary...

Second, is it possible to do this on a file I have opened (but is already typed out)?
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Find and Replace in multiple documents?

11 Dec 2017, 10:45

Hello Anime.

Welcome to the AutoHotkey community forums.

Yes, it is possible, but the solution is very case-specific. Post in the code in your autocorrection script so we can discuss translating it to work as intended.

Best wishes.
anime
Posts: 5
Joined: 11 Dec 2017, 09:57

Re: Find and Replace in multiple documents?

11 Dec 2017, 12:00

My autocorrection code? I just copied the autocorrection one linked to and replaced all the words with the library of words I wanted to replace. I only needed it to change what I typed as I typed it, I never intended to need it do work on already written text, so it wasn't an issue... but I now need it to work on text that someone else has already written, and we keep it in plain text format to avoid formatting issues... hence the txt files.

If you're asking for some functional script I've come up with, I haven't. I'm not lazy, I just suddenly (as of two weeks ago) had zero time and will continue as such for the next few weeks (pretty much until Christmas) due to a time-consuming data-heavy project for work.

My .ahk file more or less looks like this (with a longer library of words)...

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

::accessorize::accessorise
::accessorized::accessorised
::accessorizes::accessorises
::accessorizing::accessorising
::acclimatization::acclimatisation
::acclimatize::acclimatise
Again, apologies. I know I sound like an idiot. My brain is turning to mush with the other things I'm doing and sleep deprivation.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Find and Replace in multiple documents?

11 Dec 2017, 13:11

- I would output the converted files to a separate folder.
- I would use WinMerge to compare the files before and after.
- Use StrReplace to replace 'color' with 'colour' and affect words like 'colors' also.
- Or use RegExReplace with \b, in order to replace only 'color' but not words like 'colors', i.e. this is safer, but the word list must be more extensive. Also with RegEx you have to watch out for special characters:
\.*?+[{|()^$
- Consider case sensitive/case insensitive.
- UK/US publications and book titles etc should preserve their spellings. So you could have a list to 'uncorrect' certain 'corrections'.
- Do share any good links to such UK/US word lists if you have any.
- Assuming the files are txt files:

Code: Select all

q::
vList = ;continuation section
(
color|colour
colors|colours
skeptic|sceptic
skeptics|sceptics
skeptical|sceptical
)

vDir1 := A_Desktop "\MyDir"
vDir2 := A_Desktop "\MyDir" A_Now
FileCreateDir, % vDir2
Loop, Files, % vDir1 "\*", F
{
	vPath := A_LoopFileFullPath
	SplitPath, vPath, vName, vDir, vExt, vNameNoExt, vDrive
	FileRead, vText, % vPath
	Loop, Parse, vList, `n, `r
	{
		oTemp := StrSplit(A_LoopField, "|")
		vText := RegExReplace(vText, "\b" oTemp.1 "\b", oTemp.2)

		vT1 := Format("{:T}", oTemp.1)
		vT2 := Format("{:T}", oTemp.2)
		;preserve the case of mixed case words,
		;e.g. do not replace 'AutoHotkey' with 'Autohotkey',
		;actually, this sort of check probably isn't needed for this example
		;if (oTemp.1 == Format("{:L}", oTemp.1))
			vText := RegExReplace(vText, "\b" vT1 "\b", vT2)

		vU1 := Format("{:U}", oTemp.1)
		vU2 := Format("{:U}", oTemp.2)
		vText := RegExReplace(vText, "\b" vU1 "\b", vU2)
	}
	vPath2 := vDir2 "\" vName
	;note: I've assumed the UTF-8 txt encoding
	FileAppend, % vText, % "*" vPath2, UTF-8
}
Run, % vDir2
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
anime
Posts: 5
Joined: 11 Dec 2017, 09:57

Re: Find and Replace in multiple documents?

11 Dec 2017, 14:02

My replies are having to go through a moderator, so I'm sorry if they're not posting quickly.

The list I used was from: http://www.tysto.com/uk-us-spelling-list.html and IS extensive, so it already includes both "colour" and "colours" and variations of, etc.

Although it was pointed out to me that certain cases will have different results... "program" for instance would be "programme" in BE, but they also use "program" when referring to computer programs... and BE versions of the base word "license" can be different depending on whether it's a verb or something... so I'll probably have some sort of output for certain words that are more like "program[me?]" or some version, so those can be double checked.

Thanks, and I'll have to play with this later, this evening perhaps, as I'm going insane with the number of tasks I have to accomplish in the next 24 hours.
jeeswg wrote:- I would output the converted files to a separate folder.
- I would use WinMerge to compare the files before and after.
- Use StrReplace to replace 'color' with 'colour' and affect words like 'colors' also.
- Or use RegExReplace with \b, in order to replace only 'color' but not words like 'colors', i.e. this is safer, but the word list must be more extensive. Also with RegEx you have to watch out for special characters:
\.*?+[{|()^$
- Consider case sensitive/case insensitive.
- UK/US publications and book titles etc should preserve their spellings. So you could have a list to 'uncorrect' certain 'corrections'.
- Do share any good links to such UK/US word lists if you have any.
- Assuming the files are txt files:

Code: Select all

q::
vList = ;continuation section
(
color|colour
colors|colours
skeptic|sceptic
skeptics|sceptics
skeptical|sceptical
)

vDir1 := A_Desktop "\MyDir"
vDir2 := A_Desktop "\MyDir" A_Now
FileCreateDir, % vDir2
Loop, Files, % vDir1 "\*", F
{
	vPath := A_LoopFileFullPath
	SplitPath, vPath, vName, vDir, vExt, vNameNoExt, vDrive
	FileRead, vText, % vPath
	Loop, Parse, vList, `n, `r
	{
		oTemp := StrSplit(A_LoopField, "|")
		vText := RegExReplace(vText, "\b" oTemp.1 "\b", oTemp.2)

		vT1 := Format("{:T}", oTemp.1)
		vT2 := Format("{:T}", oTemp.2)
		;preserve the case of mixed case words,
		;e.g. do not replace 'AutoHotkey' with 'Autohotkey',
		;actually, this sort of check probably isn't needed for this example
		;if (oTemp.1 == Format("{:L}", oTemp.1))
			vText := RegExReplace(vText, "\b" vT1 "\b", vT2)

		vU1 := Format("{:U}", oTemp.1)
		vU2 := Format("{:U}", oTemp.2)
		vText := RegExReplace(vText, "\b" vU1 "\b", vU2)
	}
	vPath2 := vDir2 "\" vName
	;note: I've assumed the UTF-8 txt encoding
	FileAppend, % vText, % "*" vPath2, UTF-8
}
Run, % vDir2
return
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Find and Replace in multiple documents?

11 Dec 2017, 14:53

anime wrote:My autocorrection code?
(...)
My .ahk file more or less looks like this (with a longer library of words)...

Code: Select all

(...)
::accessorize::accessorize
::accessorized::accessorised
::accessorizes::accessorises
::accessorizing::accessorising
::acclimatization::acclimatisation
::acclimatize::acclimatise
Ok, you are currently using hotstrings to change the text as you type it. Instead, you should have the script:

1 - Read the contents of the file you wish to change to a variable (FileSelectFile and FileRead)
2 - Change the contents in the variable (StringReplace)
3 - Save the file with a different name (FileSelectFile and FileAppend).

You can do it like this:

Code: Select all

FileSelectFile, FILE_PATH_OUT,,, Select the file to correct, Text Files (*.txt)
FileRead, FILE_CONTENTS, %FILE_PATH_OUT%
StringReplace, FILE_CONTENTS, FILE_CONTENTS, accessorize, accessorize, All
StringReplace, FILE_CONTENTS, FILE_CONTENTS, accessorizes, accessorises, All
StringReplace, FILE_CONTENTS, FILE_CONTENTS, accessorizing, accessorising, All
StringReplace, FILE_CONTENTS, FILE_CONTENTS, acclimatization, acclimatisation, All
StringReplace, FILE_CONTENTS, FILE_CONTENTS, acclimatize, acclimatise, All
; Write any other StringReplace lines in here as needed.
FileSelectFile, NEW_FILE_PATH, S8,, Save the new file as, Text Files (*.txt)
FileAppend, %FILE_CONTENTS%, %NEW_FILE_PATH%
msgbox % "File saved succesfully."
Feel free to post any questions about the code above.
Second, is it possible to do this on a file I have opened (but is already typed out)?
Mostly yes. This is how i would go about doing it: Select the existing text and call a hotkey designed to:

1 - copy (control+c)
2 - StringReplace the contents
3 - Paste the new contents in the selection (control+v)

This should work for most types of windows and controls that you can edit. Bellow is an example using a hotkey that you can call by pressing F2 (select the text to correct and press F2 to have it corrected).

Code: Select all

F2::
Clipboard := ""
Send {Control Down}c{Control Up}
StringReplace, SELECTED_TEXT, ClipBoard, accessorize, accessorize, All
StringReplace, SELECTED_TEXT, SELECTED_TEXT, accessorizes, accessorises, All
StringReplace, SELECTED_TEXT, SELECTED_TEXT, accessorizing, accessorising, All
StringReplace, SELECTED_TEXT, SELECTED_TEXT, acclimatization, acclimatisation, All
StringReplace, SELECTED_TEXT, SELECTED_TEXT, acclimatize, acclimatise, All
; Write any other StringReplace lines in here as needed.
Clipboard := SELECTED_TEXT
Send {Control Down}v{Control Up}
Return
anime
Posts: 5
Joined: 11 Dec 2017, 09:57

Re: Find and Replace in multiple documents?

11 Dec 2017, 23:09

Thanks Gio!

I haven't had a chance to mess with the first example you showed me, however,

I was playing with the second script you wrote, as it would probably be the most immediately useful, and it was beautiful! Thank you! Is there a way to make it not change the case? When I tried it with capital letters, I figured it either wouldn't recognize it, meaning I'd have to double up the list (which is fine), or it would leave the case, but it both recognized it and made it lowercase.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Find and Replace in multiple documents?

12 Dec 2017, 02:25

- @anime: re. case, see StringCaseSense for StrReplace. RegExReplace has an i option for case sensitivity. I provided some code to handle lower/title/upper case in my post above. You can use the Format function or StringUpper/StringLower.
- I would seriously consider the RegEx approach using \b, i.e. word boundaries, because if you don't, 'disc' to 'disk' for example, could cause unwanted changes like 'discussion' to 'diskussion' (not a word).
- Thanks so much for the link to the list of words. Every word in the link is lowercase, and, a-z only (no special characters), apart from 'flyer / flier' which contains a slash.
- I've been collecting word lists here:
handy word lists - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 17&t=34588
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
anime
Posts: 5
Joined: 11 Dec 2017, 09:57

Re: Find and Replace in multiple documents?

12 Dec 2017, 10:23

@jeeswg

I could set up your code to work like Gio's clipboard version to do it in mostly any text field? Mesh the two for instance? (I'm caffeinating at the moment, please bear with me)

As for the list, I actually put the entire thing in a spreadsheet and then.. I don't remember... I think I put it in a word processor to utilize a capitalize function (I'm not lazy, I'm efficient, she tells herself), and moved that into a spreadsheet too... so I've got a file with just lowercase and one with both lower and uppercase to work with (at the time I was trying out different programs and extensions)... Someone just pointed out to me that my solution wasn't very helpful to fixing text that's already been typed, so I dug around (didn't even realize the amount of flexibility and functionality this program had) and came here because I felt like they were picking on me.

It's been such a ridiculous amount of time since I've done any coding myself that I feel like I've forgotten everything... I only half recognize any of it and am annoyed with myself.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Find and Replace in multiple documents?

12 Dec 2017, 11:01

- I would copy and paste the lists from Excel into a txt file. E.g. if the text was stored in two adjacent columns in Excel. Then in the txt file you would get lines of text of the form: 'word TAB word'. Tab-separated text.
- You could read the text into AutoHotkey using FileRead, and parse it using 'Loop, Parse', to get each line, and StrSplit, to get the words before/after the tab.
- To operate 'live', on text, e.g. in Notepad, rather than loading and outputting txt files, you could use: Clipboard := "" to empty the clipboard, and SendInput, ^c (Ctrl+C), and ClipWait, and vText := Clipboard, to put text onto the clipboard and store it in a variable.
- Hopefully with those tips and the code above you can work something out.
- AFAIC you only need a lowercase list. And you do 3 replacements for each pair of words, lower/title/upper case UK spelling to lower/title/upper case US spelling.
- You can use Format to change the case (there's an example above), or alternatively StringUpper/StringLower.
- To check if a word is lowercase you can do:
if (vText == Format("{:L}", vText)
The == in AutoHotkey, does a case sensitive comparison, whereas = by itself is case insensitive.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Guest

Re: Find and Replace in multiple documents?

12 Dec 2017, 11:29

Something like this has already been done in the past by AutoHotkey user Da Rossa https://autohotkey.com/board/topic/3205 ... rect-text/

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: filipemb, Rohwedder and 317 guests