PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Daten mit Python zeilenweise auslesen



Genschman
01-04-2010, 08:07
Liebe Gemeinde,

wer kann mir bei folgendem Problem helfen: In einer LISTE stehen mehre Begriffe zeilenweise untereinander (die Anzahl ist variiabel). In einer anderen Datei, nennen wir sie Vorlage, steht ein vordefinierter Texte mit Platzhaltern in der Form NAME1 NAME2 NAME3 usw.. Die jeweiligen Platzhalter kommen mehrfach vor. NAME1 soll nun durch den 1. Begriff aus der Liste ersetzt werden, NAME2 durch den 2. Begriff usw.
Da ich im Programieren völlig ungeübt bin, bitte ich um komplettes Skript, nicht nur ein paar Fragmente, die ich noch selbst vervollstängen muß. Am liebsten hätte ich es in Python oder AWK

Vorab vielen Dank an alle, die mir helfen wollen.

jeebee
02-04-2010, 00:31
Hmm, wenn ich dir jetzt ein vollständiges Beispiel gebe, lernst du dann etwas und kannst das nächste Mal etwas mit Fragmenten anfangen? Oder hast du gar keine Lust Programmieren zu lernen?


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re # regex
import codecs # utf8 support

# Datei file einlesen
def readfile(file):
f = codecs.open(file, 'r', 'utf-8')
lines = list()
try:
for line in f:
lines.append(line.strip())
finally:
f.close()
return lines


# Alle Vorkommnisse von placeholder in lines mit replacement ersetzen
def replace(placeholder, replacement, lines):
result = list()
def repl(m):
return replacement
regex = re.compile(placeholder)

for line in lines:
line = regex.sub(repl, line, re.U)
result.append(line)

return result


# Den Inhalt von data in file schreiben
def writefile(file, data):
f = codecs.open(file, 'w', 'utf-8')
for line in data:
f.write(line)
f.write('\n')
f.close()

# Die Hauptfunktion
def main():
names = readfile("LISTE")
count = 1
data = readfile("Vorlage.txt")
for name in names:
res = replace("NAME%d"%count, name, data)
count += 1
data = res

for line in data:
print line

writefile("Vorlage.txt.out", data)


# Skript ausführen
if __name__ == "__main__":
main()

Genschman
02-04-2010, 09:11
Lieber jeebee,
habe gerade das Skript ausprobiert und siehe da: Es funktioniert (undzar genau so, wie ich es mir gewünscht habe). Vielen vielen Dank dafür.
Nun bin ich aber der fairnesshalber auch noch Antworten schuldig:
Ehrlich gestanden habe ich vor ca. 25 Jahren (während des Studiums) das letzte mal ein kleines Programm geschrieben und seit dem nie wieder. Viel von dem Wissen ist also nicht mehr übrig (und besonders talentiert war ich auch nicht). Das mit der Lust ist halt so eine Sache ...
PS: habe den Osterhasen angewiesen, ein paar Eier extra für Dich ins Körbchen zu legen, hoffentlich ich er auch so zuverlässig wie Du.

Nochmal vielen Dank und schöne Feiertage

jeebee
02-04-2010, 13:15
Naja, da ich momentan eh dauernd mit python arbeite, wars für mich ein Aufwand von ca 10 Minuten :)... Daher: gern geschehen & auch dir schöne Ostern.

Genschman
04-04-2010, 12:57
Bin jetzt auf einen kleinen Fehler in dem Skript gestoßen: Bislang habe ich nur kleine Listen (mit max. 9 Einträgen) benutzt. Wenn es aber 10 oder mehr Einträge werden, werden die Platzhalter NAME10 NAME11 usw. wieder durch den den erste Begriff aus der LISTE ersetzt mit dem Anhang 0 1 2 usw. Konnte mir aber insofern helfen, daß ich die Formatanweisung "NAME%d" in "NAME%2d" geändert habe und die ersten neun Platzhalter in NAME 1 NAME 2 (also mit einem LEERzeichen zwischen Bustabe und Ziffer) geädert habe. Die Version NAME01 NAME02 usw. funktionier bei der Formatanweisung nicht. Kann mir jemand sagen warum? Kann aber gut sein, daß meine Platzhalternamen dackelhaft sind; wie wären sie evtl. sinnvoller?

jeebee
04-04-2010, 13:15
also für NAME02 müsstest du "NAME%02d" verwenden. Andererseits könntest du auch folgende Variante verwenden:

regex = re.compile(placeholder) mit regex = re.compile("\\b"+placeholder+"\\b") ersetzen. Dann werden nur noch ganze Wörter (von und bis zu einem Leerzeichen oder Tabulator) gematcht. Also wird zum Beispiel bei NAME10 nicht mehr NAME1 gematcht.

msi
04-04-2010, 14:44
hier eine perl variante, kurz und knackig :D



perl -npe 'open(fh,"<","LISTE") or die; @t = <fh>; $_=$1.$t[$2].$3 while /(.*)NAME(\d+)(.*)/' Vorlage.txt



bzw besser so:



perl -npe 'BEGIN { open(fh,"LISTE"); @t=<fh>; chomp @t } s/NAME(\d+)/$t[$1]/eg;' Vorlage.txt


sonst kriegst du ne zusätzliche leerzeile rein und das oben is performanter.

Genschman
04-04-2010, 21:16
Nee nee nee, lieber msi! Auf meine alten Tage werde ich nicht noch Chinesisch lernen; obwohl: Warum eigentlich nicht?! Nein, Spass bei Seite. Habe schon mal davon gehört, das man mit Perl solche Kunstücke machen kann. Und insgeheim habe ich gehofft, daß jemand diesen Einzeiler schreibt, wenn auch nur, um ihn zu sehen. Es hat schon seinen guten Grund, warum ich mir ein Python Skript gewünscht habe. Aber auch Dir ein nettes Dankeschön.