using shell commands to find and replace text

after trying to figure out the easiest and quickest way to search a file and replace a string of text it appears the quickest way it to use a shell command, which I don’t understand. :frowning:

In general, I have been duplicating a text file, renaming it, then opening it and running a search and replace.
Specifically, i need to open a file called “oldjobnum.jlt” search it for all occurrences of “oldjobnum” and replace with “newjobnum”. Then I need to save the resulting changed file in “newjobnum.jlt” without disturbing the original file.

this is what i was trying:


tell application "Finder"
	
	set volume2_ to "Jobs"
	
	if (list disks) does not contain volume2_ then
		display dialog "Reviving Jobs"
		
		mount volume "smb://192.168.1.176"
		display dialog "Jobs revived"
	else
		--display dialog "Jobs is in the building already"
	end if
	
	
	set my_dialog_result to display dialog "Old Template Number?" default answer ""
	set OldJobNum to the text returned of my_dialog_result
	set JobTemplate to OldJobNum & ".jlt"
	set TemplatePath to "Jobs:4colors:template:" & JobTemplate
	
	
	tell application "TextEdit"
		activate
		display dialog TemplatePath
		tell (open file TemplatePath)
		end tell
		set my_dialog_result to display dialog "New Template Number?" default answer ""
		set NewJobNum to the text returned of my_dialog_result
		set OldJobNum to OldJobNum as text
		set NewJobNum to NewJobNum as text
		
		set every word of front document where it = OldJobNum to NewJobNum
		close saving in "Jobs:4colors:template:" & NewJobNum & ".jlt"
		
	end tell
	
	
	
end tell

but I get no saved results in the end, nor do I get any errors. The file is correctly changed, but I’m stumped.
any ideas? I’ve seen some people chime in on similar tasks and do this whole thing in a quite and simple shell command.

thanks
david

To find and replace text in a file you can simply use the open for access command for file handling and text item delimiters to find and replace substrings in a string. I have recently answered a simultaneous question

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

I tried your suggestion, but for some reason, your read file command is not liking my file.
If I use the “Choose File” command you have it works. If I put the file path/name in there hard coded it doesn’t like it.
it comes back saying that "Finder got an error: Can’t make “Jobs:4colors:template:98765.jlt in to type file”.

Here’s my code:


set my_dialog_result to display dialog "Old Template Number?" default answer ""
	set OldJobNum to the text returned of my_dialog_result
	set my_dialog_result to display dialog "NEW Template Number?" default answer ""
	set NewJobNum to the text returned of my_dialog_result
	
	set OldJobTemplate to OldJobNum & ".jlt"
	set NewJobTemplate to NewJobNum & ".jlt"
	set OldTemplatePath to "Jobs:4colors:template:" & OldJobTemplate
	set NewTemplatePath to "Jobs:4colors:template:" & NewJobTemplate
	--display dialog TemplatePath
	
	try
		set theDupe to duplicate OldTemplatePath to folder "Jobs:4colors:template:"
		set name of theDupe to NewJobTemplate
	on error
		display dialog "cannot complete duplication of old template"
	end try
	
	
	
	set stringToFind to OldJobNum
	set stringToReplace to NewJobNum
	set TheFile to NewTemplatePath
	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
	

thanks
david

choose file returns an alias specifier,
NewTemplatePath is a HFS string path,
just write


.
set TheFile to alias NewTemplatePath
.

ok… now I get this error:

error “Finder got an error: Can’t make document file "98765.jlt" of folder "template" of folder "4colors" of disk "Jobs" into type file.” number -1700 from document file “98765.jlt” of folder “template” of folder “4colors” of disk “Jobs” to file

and… while this will solve my need, my original question was can this be done much quicker with a shell command?

david

there is no Finder tell block in your code but I suspect there is a big one.
Please put an application tell block only around specific terminology.
The only two lines which require a Finder tell block are these


.
try
	tell application "Finder"
		set theDupe to duplicate OldTemplatePath to folder "Jobs:4colors:template:"
		set name of theDupe to NewJobTemplate
	end tell
on error
	display dialog "cannot complete duplication of old template"
end try
.

hmmmm… that’s not it… I still get the same error…

error “Finder got an error: Can’t make document file "98765.jlt" of folder "template" of folder "4colors" of disk "Jobs" into type file.” number -1700 from document file “98765.jlt” of folder “template” of folder “4colors” of disk “Jobs” to file

It seems to be having a problem with the “utf8” class.

Does it matter what kind of file that the jobnumber.jlt is? It really is just a plain text file. are there different classes that would apply here?

here is my code at this point… sorry for being such a PITA.

tell application "Finder"
	
	set volume2_ to "Jobs"
	
	if (list disks) does not contain volume2_ then
		display dialog "Reviving Jobs"
		
		mount volume "smb://192.168.1.176"
		display dialog "Jobs revived"
	else
		--display dialog "Jobs is in the building already"
	end if
	
	
	set my_dialog_result to display dialog "Old Template Number?" default answer ""
	set OldJobNum to the text returned of my_dialog_result
	set my_dialog_result to display dialog "NEW Template Number?" default answer ""
	set NewJobNum to the text returned of my_dialog_result
	
	set OldJobTemplate to OldJobNum & ".jlt"
	set NewJobTemplate to NewJobNum & ".jlt"
	set OldTemplatePath to "Jobs:4colors:template:" & OldJobTemplate
	set NewTemplatePath to "Jobs:4colors:template:" & NewJobTemplate
	--display dialog TemplatePath
	
	try
		tell application "Finder"
			set theDupe to duplicate OldTemplatePath to folder "Jobs:4colors:template:"
			set name of theDupe to NewJobTemplate
		end tell
	on error
		display dialog "cannot complete duplication of old template"
	end try
	
	
	set stringToFind to OldJobNum
	set stringToReplace to NewJobNum
	set TheFile to alias NewTemplatePath
	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
	
	display dialog "complete"
	
	
	
end tell


david

remove the outer Finder tell block
insert a file specifier keyword after duplicate in this line, OldTemplatePath is just a literal string


set theDupe to duplicate file OldTemplatePath to folder "Jobs:4colors:template:"

BINGO! that solved the problem… not sure which one of those last items fixed it… I would guess the “file” insertion.

thanks a bunch!
david