views:

45

answers:

3

I am writing a script to automate the process of setting up a bunch of Mac's in a computer lab.

Each system is uniquely identified and I need a method of patching a plist file in several locations with the same string that will be read from the user in the script which is a bash script

The original string is always the same. The patching string is variable depending on the identity of the system the script is being run on. This string is read from the user at the start of the script for various other purposes and stored in $macnum.

Can anybody please provide me a simple solution that can be scripted to perform the task? Thanks.

+1  A: 

You can use some unique identifier (e.g. {{MACHINE_ID}}) in the plist and use sed to replace it:

sed -i -e 's/{{MACHINE_ID}}/'"$macnum"/g filename
strager
That gives an error message: "sed: -e expression #1, char 21: Invalid preceding regular expression". Try: `sed -i "s/{{MACHINE_ID}}/$macnum/g" filename`
Dennis Williamson
@Dennis Williamson, You're right; sorry about that. I often get confused because I switch between various regexp flavoures on a daily basis.
strager
Thanks guys, I'll try it out once I get a change and let you know how it goes. Will this replace all occurances of MACHINE_ID within the document?
Hamid
@Hamid, It will replace all occurrences of `{{MACHINE_ID}}`, including the braces. If you don't want to edit the original file, drop `-i` and the modified output will be redirected to stdout.
strager
+1  A: 
sed -i "s/plist-macnum-placeholder/$macnum/g' file ...

Where -i means edit the file "in-place" and /g says make the substitution multiple times per line and can be dropped if there is only one.

msw
I am chosing this as the Answer because it explained what the options/params mean, and I'm not the person to follow solutions blindly, I like to be able to learn from them so I can apply them in the future. More explanation regarding the s/ would have been nice too. Thanks.
Hamid
Thanks for the accept, but StackOverflow makes a poor substitute for reading the manuals. For example, knowing that sed exists allows you to formulate questions you couldn't otherwise. http://developer.apple.com/internet/opensource/opensourcescripting.html
msw
A: 

The sed-based approach strager and msw gave will work fine if the plist you're changing is in XML format, but if it's in Apple's binary format it'll probably corrupt the file format. You can use plutil to convert it to XML first:

plutil -convert xml1 filename
sed -i -e "s/placeholder/$macnum/g" filename

It shouldn't be necessary to convert it back to binary format afterward, as Apple's plist frameworks read the two formats interchangeably. Another approach would be to use PlistBuddy to edit the contents of the plist (although it'll require the script to know what entries to set to what values, rather than just replacing a placeholder):

/usr/libexec/PlistBuddy -c "set :oneentry 'value including $macnum where appropriate'" filename
/usr/libexec/PlistBuddy -c "set :anotherentry 'value including $macnum where appropriate'" filename

Finally, you can do the same thing with defaults, although it requires you specify the .plist file by full path, and leave the .plist off its name:

defaults write oneentry "value including $macnum where appropriate" /path/to/filename-without-plist
defaults write anotherentry "value including $macnum where appropriate" /path/to/filename-without-plist
Gordon Davisson
Sorry, I forgot to mention it is in standard XML because I just want to automate changes I have already made.
Hamid