PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Textdateien vergleichen?



Terrorist
16.05.2010, 14:45
Moin, habe folgendes Problem und suche hier Hilfe: Ich habe zwei Textdateien...
In der einen steht beispielsweise:

Hans spielt
gerne mit seinem
Nachbarn Karl
der Nebenan wohnt.

Nun habe ich in einer zweiten Textdatei folgendes stehen:

spielt
Nachbarn
der

Am Ende möchte ich folgendes erhalten:

Hans spielt
Nachbarn Karl
der Nebenan wohnt.

Wie muss ich das angehen? Habe bisher einige Programme gefunden die die Unterschiede anzeigen, ich brauche aber die
Gemeinsamkeiten.

Hat jemand von euch eine Idee? Bitte ausführlich beantworten... Schlage mich mit dem Problem schon ziemlich lange herum

sp1nny
16.05.2010, 15:06
Zeile für Zeile bei beiden Textdateien durchgehen.
Wenn in Zeile 1 von Textdatei 1 die Zeile 1 von Textdatei 2 enthalten ist, bleibt sie stehen. Ansonsten wird sie gelöscht.

-> strstr - C++ Reference (http://www.cplusplus.com/reference/clibrary/cstring/strstr/)

Terrorist
16.05.2010, 15:19
Hmm Danke, ich beherrsche leider kein C++ :(

sp1nny
16.05.2010, 15:21
In VB / Delphi, whatever wirds sicherlich ähnliche Funktionen geben. Wenn nicht, schreibste dir halt kurz selber eine. ;)

MfG

Terrorist
16.05.2010, 15:22
Wie soll ich mir sowas schreiben, wenn ich keinerlei Ahnung davon habe?^^
Gibts denn keine andere Möglichkeit?

Chazer2010
16.05.2010, 15:28
WinDif ist ein Programm zum Beispiel was dazu in der Lage ist. Allerdings noch aus Windows 3.1 Zeiten soweit ich weiß...

Terrorist
16.05.2010, 15:33
Mit WinDiff aka WinMerge bekommt man wohl nur die Unterschiede angezeigt...

katharinablum
16.05.2010, 17:30
vim -diff file1 file2
und dann mit regexpr alle non-matching lines entfernen.
Genaueres musst du Googlen, sollte aber gut funktionieren!

Terrorist
16.05.2010, 21:31
Okay das hat nicht wirklich geklappt.
Bei mir kommt sowas hier raus:
http://www.imagebanana.com/img/kgnf90bg/dd.jpg

btw: habe Windows. Den Befehl -diff gibts irgendwie garnicht?

Gibts denn keine Lösung? :(
Ich probiere schon den ganzen Tag an WinMerge rum, doch wenn mir mal was angezeigt wird, dann nur die Unterschiede... Ich brauche aber die Gemeinsamkeiten -.-

EBFE
16.05.2010, 23:05
Ja, dein Problem ist auch relativ speziell ;)
Außerdem beschreibst du nur einen Ausschnitt. Welches Verhalten sollte das Programm den überhaupt haben?

Erste Datei: vollständiger Text
Zweite Datei: Zeilen mit Wörtern
Ergebnis:
alle Zeilen aus der ersten Datei, in denen jeweil ein Wort aus der zweiten Datei vorkommt?

Wie soll die Suche denn von statten gehen?
1. Ein Wort aus der zweiten Datei nehmen
2. die Zeile in der ersten Datei suchen, in der das Wort vorkommt,
3. diese Zeile ins Ergebnis packen, mit dem nächsten Wort aus der zweiten Datei fortfahren ?
3.1: Soll in der zweiten Datei erst ab der Zeile, wo das vorherige Wort vorkam, fortgefahren werden?
3.2: Was soll passieren, wenn ein Wort nicht vorkommt?

Was soll z.B mit Leerzeilen in der zweiten (oder ersten Datei) passieren?
Oder falls z.B die erste Datei so ausschaut:


Hello world
ich bin
ein Satzund die zweite:


bin
world
satzsoll das Ergebniss nun so auschauen:


ich bin
ein Satzoder eher so:


Hello world
ich bin
ein Satz ?
Falls du zu dem zweiten Fall tendierst:
hier gibt es wieder weitere Fallen:


ich bin eine Zeile
und ich bin die zweite
und überhauptmit


bin
überhauptsollte es dann


ich bin eine Zeile
und ich bin die Zweite
und überhauptergeben? Oder doch nur ein Ergebnis:


ich bin eine Zeile
und überhauptUnd wie groß sind die Textdateien eigentlich? (also grob: paar MB oder doch im Gigabytebereich? )

Fragen über Fragen ;)
Aber wenn du es genauer spezifiziert hättest, hätte auch bestimmt schon jemand
ein kleines Script liefern können ;)

Edit: wie zum Beispiel dieses hier:


import sys

def file_to_lines(name):
with open(name, 'r') as f:
result = f.read()
return result.splitlines()

def main():
try:
text = file_to_lines(sys.argv[1])
words = file_to_lines(sys.argv[2])
result = [line for word in words
for line in text
if word in line.split()]

with open(sys.argv[3],'w') as f:
f.write('\n'.join(result))

except IOError:
print "Aufruf:\n",\
"filediff.py original.txt words.txt result.txt\n"

main()ist Python (und erfordert Python 2.6 (http://www.python.org/download/) zum Ausführen ;) )
einfach den code als "filediff.py" abspeichern und dann mit
filediff.py original.txt words.txt result.txt
aufrufen (original.txt = der vollständige Text, words.txt = eben die Wörter pro Zeile, result.txt = Datei, in der das Ergebis abgespeichert werden soll).
Beispiel:


C:\>more text.txt
Hans spielt
gerne mit seinem
Nachbarn Karl
der Nebenan wohnt.

C:\>more words.txt
spielt
Nachbarn
der

C:\>filediff.py text.txt words.txt result.txt

C:\>more result.txt
Hans spielt
Nachbarn Karl
der Nebenan wohnt.

Terrorist
17.05.2010, 05:12
ich bin eine Zeile
und ich bin die zweite
und überhaupt


ich bin eine Zeile
und ich bin die zweite
und überhaupt daraus sollte das werden.

Hab es mit deinem Beispiel ausprobiert. Es klappt. Aber wenn ich es mit mehreren tausend Zeilen ausprobiere, dann spinnt das Script irgendwie.

Ich werde mich heute Abend ausführlicher dazu Äußern.

Schoneinmal danke an EBFE (http://free-hack.com/../member.php?u=55471) für deine Mühe :).

btw: Die Textdateien sind nur mehrere MB groß, haben aber mehrere tausend / hunderttausend Zeilen.

sketax
17.05.2010, 07:46
Wooow sorry das ich hier so reinplatze, aber ich habe ein ähnliches problem. und zwar habe ich viele viclogs und in fast jeder accounts-datei steht nen steam account drinne
also das sieht so aus
STEAM: account
password

wie kann ich diesen bereich von sagen wir mal 150 dateien in eine extrahieren lassen?

EBFE
17.05.2010, 13:31
Hab es mit deinem Beispiel ausprobiert. Es klappt. Aber wenn ich es mit mehreren tausend Zeilen ausprobiere, dann spinnt das Script irgendwie.

Ich werde mich heute Abend ausführlicher dazu Äußern.

also
Zitat:
ich bin eine Zeile
und ich bin die zweite
und überhaupt
mit
bin
überhaupt ....
soll

ich bin eine Zeile
und ich bin die zweite
und überhaupt
ergeben.
(ok, eventuell kein wirklich gutes Beispiel).

Das würde aber heißten, dass du pro Wort in einer Datei alle Zeilen in der anderen Datei haben möchtest, in denen dieses Wort vorkommt. Insofern sollte das Script schon korrekt arbeiten (gut, es ist im Moment kein Performancewunder :) ) - es nimmt sich ein Wort und sucht alle Zeilen aus der anderen Datei, in denen dieses Wort vorkommt. Es kann ja nicht wissen, ob nur eine Zeile mit diesem Wort oder alle haben möchtest. Insofern also brauchst du schon entweder ein anderes Suchkonzept oder eine bessere Beschreibung (falls ich das nun missvestehe :) )

Terrorist
17.05.2010, 14:13
Also: Nehmen wir mal ein besseres Beispiel:

Alles.txt:



12345:test
hallo:bye
Tschüss:Hey
freehack:beste
rofl:lol
kewl:Lawl
lol:lal



"Gefiltert.txt":


hallo
lol
freehack
kewl




"Ende.txt"´:


hallo:bye
rofl:lol
lol:lal
freehack:beste
kewl:lawl



Wenn jetzt ein Wort aus Gefiltert.txt in Alles.txt vorkommt und es in 500 Zeilen vorkommt, möchte ich auch 500 Zeilen haben :-D

Wenn ich jetzt das Script starte, bleibt Ende.txt trotzdem leer...


C:\Python26>python.exe filediff.py alles.txt gefiltert.txt ende.txt

EBFE
17.05.2010, 17:09
hallo:bye




ja, das ist erstmal "programmmäßig" gesehen erstmal auch ein Wort, da zusammengeschrieben ;)
Wenn bei dir die Wörter in einem bestimmten Format vorkommen, musst du es auch sagen ;). Also z.B wenn ein Trennzeichen wie ":" oder " " (Leerzeichen) genutzt wird (das kann man ja auch übergeben lassen).

Dieses Script dürfte allgemein funktionieren:




import sys

def file_to_lines(name):
with open(name, 'r') as f:
result = f.read()
return result.splitlines()

def main():
try:
text = file_to_lines(sys.argv[1])
words = file_to_lines(sys.argv[2])
result = []
for line in text:
for word in words:
if line.find(word)>-1:
result.append(line)
break #ein Fund pro Zeile reicht


with open(sys.argv[3],'w') as f:
f.write('\n'.join(result))

except IOError:
print "Aufruf:\n",\
"filediff.py original.txt words.txt result.txt\n"

main()Sucht, ob ein Wort in der Zeile vorkommt (allerdings auch als "Subwort" bzw. als Bestandteil eines Worts). D.h es findet bei der Suche nach "lol" im
Text:


lol:hallo
lolcat:hey
helol:zeilealle 3 Zeilen

Hier die andere Version, die nur ganze Wörter findet, aber davon ausgeht, dass diese dann mit einem Trennzeichen getrennt sind - wie z.B in deinem Beispiel "lol:lal" mit ":"


iimport sys

def file_to_lines(name):
with open(name, 'r') as f:
result = f.read()
return result.splitlines()

def main():
try:
text = file_to_lines(sys.argv[1])
words = file_to_lines(sys.argv[2])
result = []

if len(sys.argv)>4:
separator = sys.argv[4]
else:
separator = ":"

for line in text:
for word in words:
if word in line.split(separator):
result.append(line)
break #es reicht, wenn ein Wort in der Zeile vorkommt


with open(sys.argv[3],'w') as f:
f.write('\n'.join(result))

except IOError:
print "Aufruf:\n",\
"filediff.py original.txt words.txt result.txt separator\n"

main()Funktioniert wie bis jetzt, nur dass du hier noch das Trennzeichen mit eingeben kannst:


filediff.py original.txt gefiltert.txt ergebnis.txt _trennzeichen_
für Trennzeichen dann : oder . oder " " (Leerzeichen - muss in " " stehen) - also das jeweilige Trennzeichen angeben.
Es können auch mehrere Zeichen sein wie ":-:" oder wonach die Daten auch immer getrennt sind. Wird kein Trennzeichen angegeben, nimmt das Script ":" als Defaultwert.

Edit/PS: beide Scripte sind jetzt so gebaut, dass eine Zeile höchstens ein mal im Ergebnis vorkommt (auch wenn da z.B mehrere Wörter drauf treffen) - falls es nicht so erwünscht ist, einfach das "break" in


break #ein Fund pro Zeile reichtlöschen.

Terrorist
17.05.2010, 21:25
Vielen vielen Dank! Es funktioniert wunderbar! Bei dem zweiten Script bekam ich einen Error, aber das lag daran, dass du iimport anstatt import geschrieben hattest xD
Aber sonst funktioniert es perfekt!