Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Newbie question: string replace

2 views
Skip to first unread message

us...@yahoo.com

unread,
Oct 25, 2005, 12:37:09 PM10/25/05
to
I have a config file with the following contents:
service A = {
params {
dir = "c:\test",
username = "test",
password = "test"
}
}

I want to find username and replace the value with another value. I
don't know what the username value in advance though. How to do it in
python?

Diez B. Roggisch

unread,
Oct 25, 2005, 12:50:07 PM10/25/05
to

Could be done using regular expressions. Ususally for such tasks one
would prefer pythons string manipulation functions, but if you want to
preserve whitespace, I think a rex is in order here:


import re, sys


new_name = "foobar"

rex = re.compile(r'(^.*username *=[^"]*")([^"]*)(".*$)')
for line in sys.stdin:
m = rex.match(line)
if m is not None:
line = "%s%s%s\n" % (m.group(1), new_name, m.group(3))
sys.stdout.write(line)

use with

python script.py < config_in > config_out

Regards,

Diez

Larry Bates

unread,
Oct 25, 2005, 1:10:37 PM10/25/05
to
I know this is not what you asked, but why not convert to a
configuration file that can be processed by ConfigParser?

[service_A]
dir=C:\test
username=test
password=test

Then you can do the following to change:

import ConfigParser
INI=ConfigParser.ConfigParser()
INI.read(r'C:\program.ini')
INI.set('service_A','username','newusername')
fp=open(r'c:\program.ini','w')
INI.write(fp)
fp.close()

Larry Bates

Steven D'Aprano

unread,
Oct 25, 2005, 1:14:55 PM10/25/05
to


Your config file looks like a cut-down mutated version of XML. Maybe you
should use real XML and the tools for working with it?

Or perhaps you should use module ConfigParser? Despite the temptation to
reinvent the wheel, it is rarely a good idea.

If you have already read the config file into a nested dictionary, then
all you need to do is:

py> service_A = ReadConfigFile() # you must write this function
py> print service_A["params"]
{'dir': 'c:\test', 'username': 'test', 'password': 'test'}
py> service_A['params']['username'] = 'J. Random User'
py> WriteConfigFile(service_A)


Or if you insist on treating the config file as a string, try something
like this:

py> s = open('filename', 'r').read()
py> print s


service A = {
params {
dir = "c:\test",
username = "test",
password = "test"
}
}

py> target = 'username = '
py> p1 = s.find(target) + len(target)
py> p2 = s.find(',\n', p1)
py> s = s[:p1] '"J. Random User"' + s[p2:]

That's not good enough for professional code, but it will get you started.


--
Steven.

davideug...@gmail.com

unread,
Oct 25, 2005, 1:26:26 PM10/25/05
to

>>> import re
>>> s = """service A = {


params {
dir = "c:\test",
username = "test",
password = "test"
}

}"""
>>> usr_str = r'username = ".*",'
>>> usr_reg = re.compile(usr_str)
>>> usr_reg.sub('username = "%s",' % ('new_usr'),s)
'service A = {\n params {\n dir = "c:\test",\n username =
"new_usr",\n password = "test"\n }\n\n}'

us...@yahoo.com

unread,
Oct 25, 2005, 2:27:39 PM10/25/05
to
So how to overwrite the config file directly in script.py instead of
running script.py with two params?

A XML file or ConfigParser is appealing but this is part of a legacy
system...:(

Mike Meyer

unread,
Oct 25, 2005, 4:48:57 PM10/25/05
to
"us...@yahoo.com" <us...@yahoo.com> writes:

> So how to overwrite the config file directly in script.py instead of
> running script.py with two params?

Don't overwrite the file directly. Save a copy, then rename it. That
way, you don't replace the new version until you know the old version
is safely written to disk, thus avoid accidently losing the data in
the file.

def modfile(filein, mod):
fileout = filein + ' temp'
fin = open(filein, 'r')
fout = open(fileout, 'w')
fout.write(mod(fin.read()))
fin.close()
fout.close()
os.unlink(filein)
os.rename(fileout, filein)

The truly paranoid will replace os.unlink(filein) with
os.rename(filein, filein + '.back').

<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

us...@yahoo.com

unread,
Oct 28, 2005, 1:37:06 PM10/28/05
to
Now it works:

rex = re.compile(r'(^.*username *=[^"]*")([^"]*)(".*$)')
for line in fileinput.input(FILE, inplace=1):

m = rex.match(line)
if m is not None:
line = "%s%s%s\n" % (m.group(1), new_name, m.group(3))
print line

But there is an extra line break after each line in FILE. Why is that?
I tried to line = "%s%s%s" % (m.group(1), new_name, m.group(3)) but it
turns out there are two extra line breaks after each line...

Steve Holden

unread,
Oct 28, 2005, 2:18:09 PM10/28/05
to pytho...@python.org
>>> for l in open('wshtest1.pys'):
... print repr(l)
...
'import sys\n'
'# WScript.Echo(str(sys.modules))\n'
'\n'
'from msg import Message\n'
'Message("Hello")\n'
'\n'
>>>

As yoyu can see, iterating over a (text) file gives you lines with a
line ending. Print adds a line ending as well. Instead use

import sys
...
...
...
sys.stdout.write(l)

You will find you lose the blank lines.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Mike Meyer

unread,
Oct 28, 2005, 3:09:37 PM10/28/05
to
"us...@yahoo.com" <us...@yahoo.com> writes:

> Now it works:
> rex = re.compile(r'(^.*username *=[^"]*")([^"]*)(".*$)')
> for line in fileinput.input(FILE, inplace=1):
> m = rex.match(line)
> if m is not None:
> line = "%s%s%s\n" % (m.group(1), new_name, m.group(3))
> print line
>
> But there is an extra line break after each line in FILE. Why is that?

Because print prints a newline after all the values you pass it.

> I tried to line = "%s%s%s" % (m.group(1), new_name, m.group(3)) but it
> turns out there are two extra line breaks after each line...

It's not clear what you mean by this. I would have expected this
change to solve the problem. Where do you get two extra newlines?

us...@yahoo.com

unread,
Oct 28, 2005, 3:27:36 PM10/28/05
to
hm...Is there a way to get rid of the newline in "print"?

us...@yahoo.com

unread,
Oct 28, 2005, 3:34:16 PM10/28/05
to
Got it, thanks all!

Steven D'Aprano

unread,
Oct 28, 2005, 7:50:29 PM10/28/05
to
On Fri, 28 Oct 2005 12:27:36 -0700, us...@yahoo.com wrote:

> hm...Is there a way to get rid of the newline in "print"?

Yes, by using another language *wink*

Or, instead of using print, use sys.stdout.write().


--
Steven.

Alex Martelli

unread,
Oct 28, 2005, 10:56:37 PM10/28/05
to
Mike Meyer <m...@mired.org> wrote:

> "us...@yahoo.com" <us...@yahoo.com> writes:
>
> > So how to overwrite the config file directly in script.py instead of
> > running script.py with two params?
>
> Don't overwrite the file directly. Save a copy, then rename it. That

See module fileinput in the standard library, it does this for you
automatically when used in the right way -- much better than rolling
your own and having to debug it and maintain it forever!


Alex

Alex Martelli

unread,
Oct 28, 2005, 10:56:37 PM10/28/05
to
Steven D'Aprano <st...@REMOVETHIScyber.com.au> wrote:

> On Fri, 28 Oct 2005 12:27:36 -0700, us...@yahoo.com wrote:
>
> > hm...Is there a way to get rid of the newline in "print"?
>
> Yes, by using another language *wink*

Ending the print statement with a comma also works;-)


> Or, instead of using print, use sys.stdout.write().

Yep, generally better than 'print'.


Alex

Don

unread,
Nov 16, 2005, 12:33:36 PM11/16/05
to
0 new messages