Tuesday, September 17, 2013

Use perl to edit multiple lines XML

Ok, here is a strange request - to edit some xml file over ssh on Mac OS X.

One needs to change false to true in following

<key>system.privilege.taskport</key> <dict> <key>allow-root</key> <false/>

Luckily, Mac OS X has perl (not sure if it was installed along with XCode). So let's use perl for that:

ssh user@192.168.1.2 "set -x; \
echo 'Password' | sudo -S \
perl -p -0777 -i -e 's@<key>system.privilege.taskport</key>.*?<dict>.*?<key>allow-root</key>.*?<false/>@<key>system.privilege.taskport</key>\n\t\t<dict>\n\t\t\t<key>allow-root</key>\n\t\t\t<true/>@sg' /etc/authorization"

Breaking this down:
  • -p tells it to loop through the input and print
  • -0777 tells it to use the end of file as the input separator, so that it gets the whole thing in in one slurp
  • -e means here comes the stuff I want you to do

And the substitution itself:
  • use @ as a delimiter so you don't have to escape /
  • use *?, the non-greedy version, to match as little as possible, so we don't go all the way to the last occurrence of </xyz> in the file
  • use the s modifier to let . match newlines (to get the multiple-line tag values)
  • use the g modifier to match the pattern multiple times
Perl expression was constructed with help of this answer from stackoverflow.

No comments:

Post a Comment