Apple Event: May 7th at 7 am PT

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Multiple find and replace

How can I make an app, with Automator, Apple Script, or some developer tool that will let me find and replace multiple items within a single document.

Here is what I need in a nutshell:

I create on-demand content for a local cable television station. I have to create individual XML files for metadata for each episode. I have made a template of the XML file, with key words in the fields that need to change. There are about twenty of them. The rest of the XML file stays the same.

Right now, I have to do a find and replace for each keyword, one at a time. (BTW, I have to use either Dashcode or Text Edit for this...)

I would like to have some kind of form or multiple find and replace feature so I can type all of my FIND fields paired with all of my REPLACE fields, then press return and have the entire XML file update.

I hope this makes sense. Any help would be appreciated.

MacG5 1.8Dual - 2GB RAM, MacBook Pro 2.4 - 4GB RAM, Mac OS X (10.5.2), FCP Studio1+2, DVC Pro25+50, AJA I/oHD, Z1U, FibreJet, Dell 2407 & 3007

Posted on Jul 26, 2008 7:27 AM

Reply
Question marked as Best reply

Posted on Jul 26, 2008 2:01 PM

Using lists and find/replace isn't that great with Automator, and it's dialogs don't even allow multiple line entries. I have a few AppleScript handlers that do most of your requirements (the multiple item edit dialog doesn't use find/replace pairs, but can use the find item as an item to edit), so I assembled a few of them into a script that should get you started. The following script reads the chosen file, prompts for the find terms (place your terms in the list as needed), puts up a dialog to edit the selected terms, does a find/replace, and finally makes a new file on the desktop with the result in it:

<pre style="
font-family: Monaco, 'Courier New', Courier, monospace;
font-size: 10px;
margin: 0px;
padding: 5px;
border: 1px solid #000000;
width: 720px; height: 340px;
color: #000000;
background-color: #FFDDFF;
overflow: auto;"
title="this text can be pasted into the Script Editor">
-- search and replace multiple items

on run
set TheFIle to choose file -- the original text file
set TheFolder to (path to desktop) -- the folder for the output file
set TheName to (GetUniqueName for TheFIle from TheFolder) -- the name for the output file
set TheText to read TheFIle -- get the text to edit

set Originals to {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"} -- the terms that can be replaced
set Originals to (choose from list Originals default items Originals with prompt "Select the terms to replace:" with multiple selections allowed) -- the specific terms to replace

set Replacements to (EditItems of Originals with Title given Prompt:"Edit the following replacement terms:") -- the replacement terms

repeat with AnItem from 1 to count Originals
set TheText to (ReplaceText of TheText from (item AnItem of Originals) to (item AnItem of Replacements))
end repeat

try -- write a new output file
tell application "Finder" to make new file at TheFolder with properties {name:TheName}
set OpenFile to open for access (result as alias) with write permission
write TheText to OpenFile starting at eof
close access OpenFile
on error errmess
try
log errmess
close access OpenFile
end try
end try

end run


to GetUniqueName for SomeFile from SomeFolder
(*
check if SomeFile exists in SomeFolder, creating a new unique name if needed
parameters - SomeFile [mixed]: a source file path
SomeFolder [mixed]: a folder to check
returns [text]: a unique file name and extension
*)
set {Counter, Divider} to {"00", "_"}

-- get the name and extension
set {name:TheName, name extension:TheExtension} to info for file (SomeFile as text)
if TheExtension is missing value then set TheExtension to ""
set TheName to text 1 thru -((count TheExtension) + 2) of TheName

set NewName to TheName & "." & TheExtension
tell application "System Events" to tell (get name of files of folder (SomeFolder as text))
repeat while it contains NewName
set Counter to text 2 thru -1 of ((100 + Counter + 1) as text) -- leading zero
set NewName to TheName & Divider & Counter & "." & TheExtension
end repeat
end tell

return NewName
end GetUniqueName


to EditItems of SomeItems given Title:TheTitle, Prompt:ThePrompt
(*
displays a dialog for multiple item edit (note that a return is used between each edit item)
for each of the items in SomeItems, a line containing it's text is placed in the edit box
the number of items returned are padded or truncated to match the number of items in SomeItems
parameters - SomeItems [list]: a list of text items to edit
TheTitle [boolean/text]: use a default or the given dialog title
ThePrompt [boolean/text]: use a default or the given prompt text
returns [list]: a list of the edited items, or {} if error
*)
set {TheItems, TheInput, TheCount} to {{}, {}, (count SomeItems)}
if TheCount is less than 1 then return {} -- error

if ThePrompt is in {true, false} then -- "with" or "without" Prompt
if ThePrompt then
set ThePrompt to "Edit the following items:" & return -- default
else
set ThePrompt to ""
end if
else -- fix up the given prompt a little
set ThePrompt to ThePrompt & return
end if

if TheTitle is in {true, false} then if TheTitle then -- "with" or "without" Title
set TheTitle to "Multiple Edit Dialog" -- default
else
set TheTitle to ""
end if

set {TempTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
set {SomeItems, AppleScript's text item delimiters} to {SomeItems as text, TempTID}

set TheInput to paragraphs of text returned of (display dialog ThePrompt with title TheTitle default answer SomeItems)

repeat with AnItem from 1 to TheCount -- pad/truncate entered items
try
set the end of TheItems to (item AnItem of TheInput)
on error
set the end of TheItems to ""
end try
end repeat
return TheItems
end EditItems


to ReplaceText of SomeText from OldItem to NewItem
(*
replace all occurances of OldItem with NewItem
parameters - SomeText [text]: the text containing the item(s) to change
OldItem [text]: the item to be replaced
NewItem [text]: the item to replace with
returns [text]: the text with the item(s) replaced
*)
set SomeText to SomeText as Unicode text -- TID's are case insensitive with Unicode text
set {TempTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, OldItem}
set {ItemList, AppleScript's text item delimiters} to {text items of SomeText, NewItem}
set {SomeText, AppleScript's text item delimiters} to {ItemList as text, TempTID}
return SomeText
end ReplaceText
</pre>

HTH
21 replies

Apr 21, 2015 2:58 AM in response to red_menace

Hi.


Sorry to drag this thread up again but I thought you might be able to help me with a multiple find/replace issue. I have very basic applescript understanding but I have managed to compile an extremely inelegant script to extract 3 lists of data. uniqueList4 contains the data that I want to apply the changes to, uniqueList5 contains the original terms that I want to replace (if they are found on List1) and uniqueList6 contains the corresponding replacement terms. I just don't know how to take it any further. It would be wonderful if someone could help me with this.



set fileRefr to (open for access filePath)

set theText to (read fileRefr)

set textList to paragraphs of theText

close access fileRefr

set theCNT to (count of textList) - 1



set uniqueList4 to {}

set dataList4 toevery paragraph of (do shell script"cat " & quoted form of POSIX path of filePath & " | awk -F'" & tab & "' 'BEGIN{getline}{print $8}'")

set uniqueList4 to uniqueList4 & dataList4



set fileRefr2 to (open for access filePath2)

set theText2 to (read fileRefr2)

set textList2 to paragraphs of theText2

close access fileRefr2

set theCNT2 to (count of textList2) - 1

set theCNT3 to count of textList2


set uniqueList5 to {}

set dataList5 toevery paragraph of (do shell script"cat " & quoted form of POSIX path of filePath2 & " | awk -F'" & tab & "' 'BEGIN{getline}{print $1}'")

set uniqueList5 to uniqueList5 & dataList5


set uniqueList6 to {}

set dataList6 toevery paragraph of (do shell script"cat " & quoted form of POSIX path of filePath2 & " | awk -F'" & tab & "' 'BEGIN{getline}{print $2}'")

set uniqueList6 to uniqueList6 & dataList6


repeatwith i from 2 to count theCNT3

set uniqueList4 to (ReplaceText of uniqueList4 from (item i of uniqueList5) to (item i of uniqueList6))

endrepeat

Jan 22, 2016 3:22 AM in response to BDAqua

Thank you for the reply.

It could work in this overly simplified example, but these suggestions will unfortunately not work in more general cases, for instance when the words to be replaced are in the beginning of lines, or followed by punctuation characters.

It would be better to find the properties corresponding to "exact match"...

Multiple find and replace

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.