I have absolutely no knowledge of coding or whatsoever. But on a daily routine I have to open a file in TextEdit for Mac to open a .txt file and find and replace several text instances. Not difficult, but it would be great to have an automated solution for this (saving time and avoiding human error).
Looking on this site, I've found this interesting script by dj bazzie wazzie, and with Automator even I can get it to work, so that's hopeful! 😉
set stringToFind to "replace that"
set stringToReplace to "with this"
set theFile to choose file
set theContent to read theFile as «class utf8»
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, stringToFind}
set ti to every text item of theContent
set AppleScript's text item delimiters to stringToReplace
set newContent to ti as string
set AppleScript's text item delimiters to oldTID
try
set fd to open for access theFile with write permission
set eof of fd to 0
write newContent to fd as «class utf8»
close access fd
on error
close access theFile
end try
However, I need to change not 1 but 3 things in the file. How can I adapt this code in a way that not "replace that" is replaced by "with this", but e.g. "unripe apple" by "ripe apple", "unripe kiwi" by "ripe kiwi" and "unripe banana" by "ripe banana"?
I've been puzzling on this, and probably the answer is way easier than expected, as I am quite a noob, I haven't managed to come to a solution.
Ideas on this are very welcome. Many thanks in advance!
The example AppleScript code, shown below, was tested in Script Editor under macOS Catalina with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.
Example AppleScript code:
set textToFindList to {"unripe apple", "unripe kiwi", "unripe banana"}
set textToReplaceWithList to {"ripe apple", "ripe kiwi", "ripe banana"}
if (length of textToFindList) is not equal to ¬
(length of textToReplaceWithList) then return
set theFile to choose file
-- tell application "Finder" to duplicate file theFile with exact copy
set theText to read theFile as «class utf8»
repeat with i from 1 to length of textToFindList
set theText to my findAndReplaceInText(theText, ¬
item i of textToFindList, ¬
item i of textToReplaceWithList)
end repeat
my writeToFile(theText, theFile, true)
-- # Handlers #
on findAndReplaceInText(theText, theSearchString, theReplacementString)
--considering case
set AppleScript's text item delimiters to theSearchString
set theTextItems to every text item of theText
set AppleScript's text item delimiters to theReplacementString
set theText to theTextItems as string
set AppleScript's text item delimiters to ""
return theText
--end considering
end findAndReplaceInText
on writeToFile(theText, theFile, overwriteExistingContent)
try
set theFile to theFile as string
if theFile contains "/" then
set theOpenedFile to open for access theFile with write permission
else
set theOpenedFile to open for access file theFile with write permission
end if
if overwriteExistingContent is true then set eof of theOpenedFile to 0
write theText to theOpenedFile starting at eof
close access theOpenedFile
return true
on error
try
close access file theFile
end try
return false
end try
end writeToFile
Notes:
The writeToFile(theText, theFile, overwriteExistingContent)
handler is a slightly modified handler from: Reading and Writing Files
The handler from the linked Apple support document was modified to handle both POSIX and HFS+ file paths.
The findAndReplaceInText(theText, theSearchString, theReplacementString)
handler if from Finding and Replacing Text in a String from: Manipulating Text
If you need case sensitive find/replace then uncomment the --considering case
and --end considering
lines of code in the on findAndReplaceInText(theText, theSearchString, theReplacementString)
handler.
If you'd to automatically make a backup copy of the file, before editing it, then remove --
from in front of the following line of code_:
tell application "Finder" to duplicate file theFile with exact copy
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5
, with the value of the delay set appropriately.