Hallo,
ich habe folgendes vor: ich öffne eine Datei und möchte nur die Zahlen verändern... Die Datei öffnen ist kein problem, aber das mit dem verändern der Zahlen ist etwas, was ich nicht weiß.
Die Datei ist wie folgt aufgebaut:
Text 123 Text
Text 123 Text
Text 123 Text
...
Nun möchte ich aber nur die Zahlen verändern... wie kann ich das machen? Ist das mit replace() möglich?
Mfg
Zahlen in Datei verändern
@DiiiDiii: Das kann man nicht so allgemein beantworten. Der geeignete Weg hängt davon ab wie die Zeilen aufgebaut sind und wie man die Zahlen identifizieren kann die ausgetauscht werden sollen. So ganz allgemein kann man natürlich ``new_text = text.replace('123', 'was anderes')`` schreiben wenn man den alten Wert der Zahlen kennt. *Das* hättest Du aber ganz einfach ausprobieren können.
Du könntest die Datei mit dem csv-Modul einlesen und schreiben. Zwischen Lesen und Schreiben kannst du problemlos den Wert ändern.DiiiDiii hat geschrieben:Danke, ja das weiß ich... nur die Frage ist wie ich die Zahlen verändere... das ist mein problem... Da weiß ich gerade leider nicht weiter
Versuch mal einen Ansatz und frag dann bei Problemen noch mal. Solltest du mit dem Ansatz schon Probleme haben, dann frag sofort.
Bisher ist das mein Ansatz:
Die Zahlen in der Datei weiß ich natürlich nicht, die sollen immer wieder verändert werden. Ich habe es mal mit re versucht, allerdings bekomme ich dann folgende Meldung:
Code: Alles auswählen
#!/usr/bin/python
import os
import re
import random
for root, dirs, filenames in os.walk("/root/collectd-python/superplugin/"):
for dir in dirs:
pass
for filename in filenames:
f = open(root +"/" + filename, "r")
lines = f.readlines()
f.close()
number = random.randint(500,600)
re.sub(r'([\d.]*\d+)', number, lines)
f = open(root +"/" + filename, "w")
f.writelines()
f.close()
Code: Alles auswählen
TypeError: object of type 'int' has no len()
Du hast noch ein paar kleine Macken in deinem Programm. Du versuchst zum Beispiel den regulären Ausdruck direkt auf der Liste arbeiten zu lassen, statt auf einem einzelnen Element der Liste.DiiiDiii hat geschrieben:Code: Alles auswählen
TypeError: object of type 'int' has no len()
So könnte es aussehen, obwohl es auch dort noch Verbesserungspotenzial gibt.
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import unicode_literals
import os
import re
import random
def main():
path = os.path.join(os.path.dirname(__file__), 'data')
for root, dirs, filenames in os.walk(path):
for filename in filenames:
with open(os.path.join(root, filename), 'r') as f:
lines = f.readlines()
for i, line in enumerate(lines):
number = random.randint(500, 600)
lines[i] = re.sub(r'(\d+)', str(number), line)
with open(os.path.join(root, filename), 'w') as f:
f.writelines(lines)
print(lines)
if __name__ == '__main__':
main()
@DiiDii: öffne Dateien mit "with". Zum Pfade Zusammensetzen gibt es os.path.join. Du solltest die Datei nicht direkt überschreiben, sondern erst eine modifizierte Datei und diese dann umbenennen.
@/me: das mit enumerate und Liste verändern ist unschön.
Code: Alles auswählen
#!/usr/bin/python
import os
import re
import random
def substitute(line):
number = random.randint(500, 600)
return re.sub(r'\d+', str(number), line)
def main():
path = "/root/collectd-python/superplugin/"
for root, _, filenames in os.walk(path):
for filename in filenames:
filename_in = os.path.join(root, filename)
filename_out = filename_in+'.mod'
with open(filename_in, 'r') as fin, open(filename_out, 'w') as fout:
fout.writelines(map(substitute,fin))
os.rename(filename_out, filename_in)
if __name__ == '__main__':
main()
Klar ist es das. Ich wollte nur erst einmal einigermaßen dicht am ursprünglichen Code bleiben um den Threadstarter nicht abzuhängen. Ich wusste ja, dass dann anschließend noch bessere Lösungen kommen.Sirius3 hat geschrieben:@/me: das mit enumerate und Liste verändern ist unschön.
Falls die Größe der Datei überschaubar ist und man somit keinen allzu hohen Speicherverbrauch befürchten muss, dann kann man auch den kompletten Datei-Inhalt an `re.sub()` übergeben, sowie eine Funktion mitgeben, die für jede Ersetzung aufgerufen wird. Diese würde dann die jeweils nächste Zufallszahl erzeugen. Beispiel:
Code: Alles auswählen
#!/usr/bin/env python2
import random
import re
def replace_numbers(s):
def replacer(m):
return str(random.randint(500, 600))
return re.sub('\d+', replacer, s)
def main():
text = 'bla 000 sgfsg\nblupp 000 jglfsg\nmauz 000 hsdkgfh'
print replace_numbers(text)
if __name__ == '__main__':
main()