Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pyparsing: How can I parse data and then edit a specific value in a .txt file?

my data is located in a .txt file (no, I can't change it to a different format) and it looks like this:

varaiablename = value
something = thisvalue
youget = the_idea

Here is my code so far (taken from the examples in Pyparsing):

from pyparsing import Word, alphas, alphanums, Literal, restOfLine, OneOrMore, \
empty, Suppress, replaceWith

input = open("text.txt", "r")
src = input.read()

# simple grammar to match #define's
ident = Word(alphas + alphanums + "_")
macroDef = ident.setResultsName("name") + "= " + ident.setResultsName("value") + Literal("#") + restOfLine.setResultsName("desc")
for t,s,e in macroDef.scanString(src):
print t.name,"=", t.value

So how can I tell my script to edit a specific value for a specific variable?
Example:
I want to change the value of variablename, from value to new_value. So essentially variable = (the data we want to edit).

I probably should make it clear that I don't want to go directly into the file and change the value by changing value to new_value but I want to parse the data, find the variable and then give it a new value.

like image 655
Sember Avatar asked Dec 20 '10 21:12

Sember


2 Answers

Even though you have already selected another answer, let me answer your original question, which was how to do this using pyparsing.

If you are trying to make selective changes in some body of text, then transformString is a better choice than scanString (although scanString or searchString are fine for validating your grammar expression by looking for matching text). transformString will apply token suppression or parse action modifications to your input string as it scans through the text looking for matches.

# alphas + alphanums is unnecessary, since alphanums includes all alphas
ident = Word(alphanums + "_")
# I find this shorthand form of setResultsName is a little more readable
macroDef = ident("name") + "=" + ident("value")

# define values to be updated, and their new values
valuesToUpdate = {
    "variablename" : "new_value"
    }

# define a parse action to apply value updates, and attach to macroDef
def updateSelectedDefinitions(tokens):
    if tokens.name in valuesToUpdate:
        newval = valuesToUpdate[tokens.name]
        return "%s = %s" % (tokens.name, newval)
    else:
        raise ParseException("no update defined for this definition")
macroDef.setParseAction(updateSelectedDefinitions)

# now let transformString do all the work!
print macroDef.transformString(src)

Gives:

variablename = new_value
something = thisvalue
youget = the_idea
like image 58
PaulMcG Avatar answered Nov 13 '22 14:11

PaulMcG


For this task you do not need to use special utility or module What you need is reading lines and spliting them in list, so first index is left and second index is right side. If you need these values later you might want to store them in dictionary.

Well here is simple way, for somebody new in python. Uncomment lines whit print to use it as debug.

f=open("conf.txt","r")
txt=f.read() #all text is in txt
f.close()

fwrite=open("modified.txt","w")
splitedlines = txt.splitlines():
#print splitedlines 
for line in splitedlines:
    #print line
    conf = line.split('=')
    #conf[0] is what it is on left and conf[1] is what it is on right
    #print conf
    if conf[0] == "youget":
        #we get this
        conf[1] = "the_super_idea" #the_idea is now the_super_idea
    #join conf whit '=' and write
    newline = '='.join(conf)
    #print newline
    fwrite.write(newline+"\n")

fwrite.close()
like image 33
Luka Rahne Avatar answered Nov 13 '22 16:11

Luka Rahne