I'm trying to make a tool that will replace a single line in a .yml file(opens as a text document). I have it writing to the file, but it takes everything out and writes the "fixed" line. My code is below, along with a sample of one instance/file. The file names are IMPORTANT and can not change.
import sys
from os import listdir
from os.path import isfile, join
onlyfiles = [ f for f in listdir() if isfile(f) and str(f)[-4:]==".yml" ] #Gets the file names, can be ANYTHING
for pos in range(1, len(onlyfiles)): #So it stops at the end of the List
with open(onlyfiles[pos], 'r') as a: #Lets open it make sure it is good
for line in a:
if line == " world: Trolling\n": # this is the target line to replace
line = line.replace(" world: Trolling", " world: world\n") #rework the line, though it wont write even if i change the R to W
with open(onlyfiles[pos], 'w') as repl: #Writes to the file, but gets rid of everything else
repl.write(line)
print(line)
Sample of un-modified document:
timestamps:
login: 1373913158118
lastteleport: 1373918169442
logout: 1373918539235
kits:
trusted: 1373052268213
ipAddress: 142.165.45.129
nickname: Erin
lastlocation:
world: Trolling
x: -890.6999999880791
y: 87.0
z: -764.6999999880791
yaw: 91.99242
pitch: 75.449974
homes:
e:
world: Trolling
x: 4653.2140183238
y: 64.0
z: 80.02726116652944
yaw: 192.08363
pitch: 66.29998
I'm trying to replace instances of "Trolling" with "world", across 100+ files, without touching anything else
You need an else
condition after if line == " world: Trolling\\n"
for when the line does not match this pattern. Also put all the data you're writing back into some variable and write that in one shot at the end after closing the file you're reading from, you cannot read and write to a file at the same time.
import sys
from os import listdir
from os.path import isfile, join
onlyfiles = [ f for f in listdir() if isfile(f) and str(f)[-4:]==".yml" ]
for file in onlyfiles:
wdata = ''
with open(file, 'r') as a: #Lets open it make sure it is good
for line in a:
if line == " world: Trolling\n":
line = " world: world\n" # You already know what it should be
print line
wdata += line
with open(file, 'w') as repl:
repl.write(wdata)
It's probably easier to just do
for file in onlyfiles:
with open(file, 'r') as f:
d = f.read().replace('\n world: Trolling\n','\n world: world\n')
with open(file, 'w') as f:
f.write(d)
I would probably go for a more general solution.
import yaml
def replace(doc, inval, outval):
if isinstance(doc, dict):
for k, v in doc.items():
if v == inval:
doc[k] = outval
elif isinstance(v, dict):
doc[k] = replace(v, inval, outval)
elif isinstance(v, list):
for i, item in enumerate(v[:]):
doc[k][i] = replace(item, inval, outval)
return doc
doc = yaml.load(open("original.yml"))
newdoc = replace(doc, "Trolling", "world")
yaml.dump(newdoc, open("modified.yml", "w"))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.