Replacing text in line starting with XYZ with other text

Hi all,
I’m tinkering with some kind of installer for http://www.sierrahelp.com (a site that helps installing classic dos games and playing them with Dosbox - up to now only having Windows installers) and I made some good progress.
Now I need to edit a dosbox config file (pure text).

I know the location of the source file (the installer first moves the config to /tmp) and name “dosbox.conf” and the location will be ~/library/application support/sierrahelp/dosbox.conf - and I know how to find/access the files with applescript.
The problem is that the dosbox.conf file has two lines I need to edit but the content of the lines vary depending on the game. Also the lines are not always at the same line number, so I can’t find them through that.
The two lines are:
captures= “some Windows path”
mount c “some other Windows path”

The Windows path of capture will be set to always the same path on OS X (~/library/application support/sierrahelp/capture) and the path I need to set in the mount line will be a variable set in the script.

So my question is, can I find the lines via AppleScript just by the line starting words (capture and mount) and then replace the whole line?
Reading through the delimiter stuff made my mind smoke, but couldn’t find the solution for this.

Unfortunately, AppleScript delimiters are indeed the way to go. Give an example of what you want to find.


set tid to AppleScript's text item delimiters
set applescript's text item delimiters to ""
set tParts to text items of theSourceStuff
set AppleScript's text item delimiters to tid

-- Say confText is the text of your source file,
-- someWindowsPath is the captures path,
-- and someOtherWindowsPath is the other path.

set theLines to paragraphs of confText
repeat with i from 1 to (count theLines)
	set thisLine to item i of theLines
	if (thisLine begins with "captures=") then
		set item i of theLines to "captures= \"" & someWindowsPath & "\"" -- assuming you need literal quotes in the line.
	else if (thisLine begins with "mount c") then
		set item i of theLines to "mount c \"" & someOtherWindowsPath & "\"" -- ditto.
	end if
end repeat

set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to return & linefeed -- assuming DOS line endings needed.
set newConfText to theLines as text
set AppleScript's text item delimiters to astid

-- Now write newConfText back to the file.

Dominus; think of them this way: If I ask you to count the words in a document, you use space as your delimiter, as your separator of words. You make a list of all the blocks of text that aren’t spaces. I wrote a tutorial about them some years ago: “Using AppleScript’s Text Item Delimiters” where I said:

Read that. It’ll help.

Hi, Dominus. (Domine?)

The ‘write’ line should be:

write newConfText to file conftext -- NB. file specifier, not just a path.

Also, you’ve set theLines to the paragraphs of the path, not to the paragraphs of the contents of the file.

When you use ‘open for access’, it’s best to use the reference number it returns, rather than further file specifications, in the subsequent Read/Write commands. It’s faster and avoids certain possible confusions.

set someWindowsPath to "Blubblub"
set someOtherWindowsPath to "blabla"
set conftext to ((path to desktop as text) & "test.txt")

set fRef to (open for access file conftext with write permission) -- Open an access and store the returned access reference number.
try
	set theLines to paragraphs of (read fRef as text)
	repeat with i from 1 to (count theLines)
		set thisLine to item i of theLines
		if (thisLine begins with "captures=") then
			set item i of theLines to "captures= \"" & someWindowsPath & "\"" -- assuming you need literal quotes in the line.
		else if (thisLine begins with "mount c") then
			set item i of theLines to "mount c \"" & someOtherWindowsPath & "\"" -- ditto.
		end if
	end repeat
	
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to return & linefeed -- assuming DOS line endings needed.
	set newConfText to theLines as text
	set AppleScript's text item delimiters to astid
	
	set eof fRef to 0 -- "Empty" the file before writing new, possibly shorter data to it.
	write newConfText as text to fRef
	close access fRef
on error errMsg number errNum
	close access fRef
	error errMsg number errNum
end try

thanks that did it.
When I have the installer script all done, I’ll post it (and will probably get told that it can be done much easier :)).

I wrote a tutorial some years ago: “Using AppleScript’s Text Item Delimiters” which started with:

Read the rest and it might help.

yes, I found that tutorial right away and tried to understand it before posting for help, but I couldn’t. Just file it as a weirdness of my brain… :slight_smile:
I have one excuse, and that is that I have a new born at home and currently my only time to look into this is at night between two feeding times. So I’m really a bit tired all the time and have a hard time to concentrate on the delimiters things.
Looking at the full script and knowing exactly what the result is, makes it dawn a bit but not entirely.

@Adam, did you mess up my post from 2011-04-10 12:07:04 am ? Seems your reply to me got exchanged with my text

@Nigel, having a go at the script again, I found that this is NOT working for some reason. The last script you gave me has two problems:

  1. it only works if the “captures” or the “mount c” lines are the first line of the text
  2. if that is the case the script will only do the replacement for the line it finds first and replaces all lines with this.

For example if the text is

The script will not do anything to the text (except copy all the lines and write the file - tested by leaving out “set eof fRef to 0”, this way the text gets appended at the end).

If the text is

the result is

Sincere apologies. There was a typo in the script. The first line inside the repeat should be:

set thisLine to item i of theLines

Not:

set thisLine to item 1 of theLines

I’ve corrected my script(s) above.

Thanks a lot, now it works as intended.