gcazian has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am working a program that will change a password in the password file (username.xml) on my Jabber server.

Snippet from the username.xml file:

<xdb><password xmlns='jabber:iq:auth' xdbns='jabber:iq:auth'>password</password>

Snippet of code to change the password:

open(FILE, "$jabuserdir/$username.xml"); while (<FILE> ) { s/xdbns='jabber:iq:auth'>(.*)</$usernewpwd/g ; } close( FILE );
I can't seem to get the code to change the password. What am I doing wrong? Forgive me, I'm a newbie.

Replies are listed 'Best First'.
Re: editing a file with regular expressions
by BrowserUk (Patriarch) on Jan 29, 2004 at 00:20 UTC

    All you have done is edit a copy of the line in memory, not the file itself. You would need to write the modified output to new file, close it, delete the original and then rename the new file back to the original name.

    For a simple mechanism for 'inplace editing' and a piece of example code see perlrun and the description on the -i[ext] switch.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Timing (and a little luck) are everything!

Re: editing a file with regular expressions
by borisz (Canon) on Jan 29, 2004 at 00:17 UTC
    I think you missed to save changes ;-) try this, ( but on a backup it edits the file inplace ):
    perl -i -pe 's!(xdbns=.jabber:iq:auth.>)[^<]*(</password)!$1your_passw +ord$2!g' your_user_file.xml

    Update: I messed up the regex

    Boris
Re: editing a file with regular expressions
by ysth (Canon) on Jan 29, 2004 at 00:19 UTC
    Assuming you want to replace password (in your example) with $usernewpwd, you need to make sure you preserve the "xdbns='jabber:iq:auth'>" and "<" parts, by including them in the replacement. So:
    s/xdbns='jabber:iq:auth'>.*?</xdbns='jabber:iq:auth'>$usernewpwd</g;
    or
    s/(xdbns='jabber:iq:auth'>).*?(<)/$1$usernewpwd$2/g;
    Note that I changed .* to .*?; this will cause it to prefer to stop matching at the first < instead of going on to a later < on the line.

    Have you considered quoting issues? E.g. if a password actually contains a character like "<", what will whatever usually builds the file put there? And can you do it the same way to $usernewpwd, and adjust the regex to handle it? It might be better to look to one of the fine XML modules available on CPAN, than do it by hand.

    Update: And as Boris says, you need to make sure to actually write out the changed lines to a new file.