6

I'am new to Python 3 and could really use a little help. I have a txt file containing:

InstallPrompt=

DisplayLicense=

FinishMessage=

TargetName=D:\somewhere

FriendlyName=something

I have a python script that in the end, should change just two lines to:

TargetName=D:\new

FriendlyName=Big

Could anyone help me, please? I have tried to search for it, but I didnt find something I could use. The text that should be replaced could have different length.

Jordan Running
  • 102,619
  • 17
  • 182
  • 182
user302935
  • 407
  • 3
  • 6
  • 11

5 Answers5

5
import fileinput
for line in fileinput.FileInput("file",inplace=1):
    sline=line.strip().split("=")
    if sline[0].startswith("TargetName"):
        sline[1]="new.txt"
    elif sline[0].startswith("FriendlyName"):
        sline[1]="big"
    line='='.join(sline)    
    print(line)
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
2

A very simple solution for what you're doing:

#!/usr/bin/python
import re
import sys
for line in open(sys.argv[1],'r').readlines():
  line = re.sub(r'TargetName=.+',r'TargetName=D:\\new', line)
  line = re.sub(r'FriendlyName=.+',r'FriendlyName=big', line)
  print line,

You would invoke this from the command line as ./test.py myfile.txt > output.txt

Dan Story
  • 9,985
  • 1
  • 23
  • 27
2

Writing to a temporary file and the renaming is the best way to make sure you won't get a damaged file if something goes wrong

import os
from tempfile import NamedTemporaryFile
fname = "lines.txt"

with open(fname) as fin, NamedTemporaryFile(dir='.', delete=False) as fout:
    for line in fin:
        if line.startswith("TargetName="):
            line = "TargetName=D:\\new\n"
        elif line.startswith("FriendlyName"):
            line = "FriendlyName=Big\n"
        fout.write(line.encode('utf8'))
    os.rename(fout.name, fname)
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
2

Is this a config (.ini) file you're trying to parse? The format looks suspiciously similar, except without a header section. You can use configparser, though it may add extra space around the "=" sign (i.e. "TargetName=D:\new" vs. "TargetName = D:\new"), but if those changes don't matter to you, using configparser is way easier and less error-prone than trying to parse it by hand every time.

txt (ini) file:

[section name]

FinishMessage=

TargetName=D:\something

FriendlyName=something

Code:

import sys
from configparser import SafeConfigParser

def main():
    cp = SafeConfigParser()
    cp.optionxform = str # Preserves case sensitivity
    cp.readfp(open(sys.argv[1], 'r'))
    section = 'section name'
    options = {'TargetName': r'D:\new',
               'FriendlyName': 'Big'}
    for option, value in options.items():
        cp.set(section, option, value)
    cp.write(open(sys.argv[1], 'w'))

if __name__ == '__main__':
    main()

txt (ini) file (after):

[section name]

FinishMessage = 

TargetName = D:\new

FriendlyName = Big
jfs
  • 399,953
  • 195
  • 994
  • 1,670
0

subs_names.py script works both Python 2.6+ and Python 3.x:

#!/usr/bin/env python
from __future__ import print_function
import sys, fileinput

# here goes new values
substitions = dict(TargetName=r"D:\new", FriendlyName="Big")

inplace = '-i' in sys.argv # make substitions inplace
if inplace:
   sys.argv.remove('-i')

for line in fileinput.input(inplace=inplace):
    name, sep, value = line.partition("=")
    if name in substitions:
       print(name, sep, substitions[name], sep='')
    else:
       print(line, end='')

Example:

$ python3.1 subs_names.py input.txt
InstallPrompt=

DisplayLicense=

FinishMessage=

TargetName=D:\new

FriendlyName=Big

If you are satisfied with the output then add -i parameter to make changes inplace:

$ python3.1 subs_names.py -i input.txt
jfs
  • 399,953
  • 195
  • 994
  • 1,670