[PHP] file compare

Pagina: 1
Acties:
  • 110 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Anoniem: 128202

Topicstarter
Ik wil graag en php pagina maken die de verschillen tussen 2 bestanden wegschrijft in een derde bestand (om zo alleen de updates is het 3e bestand te zetten).
In command kun je zeer gemakkelijk doen met file compare (fc 1.txt 2.txt -> 3.txt).
Hoe doe ik dit met behulp van php (en dus niet door bijv. lijn1 van 1.txt te pakken en dan alle lijnen door te gaan van 2.txt om te kijken of hij er in voor komt (de tekstbestanden hebben namelijk 29 000 regels en dan moet het 29 000 x 29 000 = 841 000 000 stappen doen / regels vergelijken)).
Weet iemand hievoor een functie?

Dus niet iets in de trend:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$open1 = file ("1.txt");
foreach ($open1 as $regel1){
    $open2 = file ("2.txt");
    $nieuwelijn = "ja";
    foreach ($open2 as $regel2){
        if ($regel1 == $regel2){
            $nieuwelijn = "nee";
        }
    }
    if ($nieuwelijn == "ja"){
        $fp = fopen("3.txt", "a+");
        fwrite ($fp, "$regel1
        ");
        fclose ($fp);
    }
}
?>

Acties:
  • 0 Henk 'm!

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 13-06 10:21
kun je niet de system() functie gebruiken om compare uit te voeren (aangenomen dat je linux gebruikt)

Acties:
  • 0 Henk 'm!

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

PHP:
1
2
3
4
if (file_get_contents('1.txt') === file_get_contents('2.txt'))
  {
    echo 'He, wij zijn hetzelfde';
  }

Zoiets?

Sole survivor of the Chicxulub asteroid impact.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 04-07 15:03

NMe

Quia Ego Sic Dico.

offtopic:
Wel eens van booleans gehoord? :? $nieuwelijn zou een boolean moeten zijn. 8)7

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Anoniem: 135134

Wat dacht je van 2 hashes aanmaken van beiden bestanden en deze vergelijken? Om alleen te kijken of de bestanden gelijk zijn lijkt mij dat wel voldoende. De kans dat 2 bestanden dezelfde hash opleveren is redelijk klein. Als je bijna helemaal zeker wil zijn vergelijk je de hash (of md5 of sha1) van de bestanden en de bestandsgrootte. Hele grote kans dat als beide overeenkomen dat de bestanden hetzelfde zijn en het is misschien wat minder geheugen intensief. Daarbij werkt op zowel linux al windows systemen.

Als je dan de verschillen wil wegschrijven zou ik geen gebruik maken van file_get_contents of file, omdat hij dan beide bestanden in het geheugen gaat zetten. Je kunt dan beter gewoon de fopen gebruiken en dan fgets om elke keer uit elk bestand 1 regel te halen. Is minder geheugen intensief en waarschijnlijk ook sneller.

Of zoek even op google, er zijn gewoon filecompare classes en functies al gemaakt door mensen. Maar ik ben toch bang dat als je het cross platform wil houden, dat ze ergens wel een compare van de regels hebben gebruikt, dus als ze dat ook niet mogen doen omdat je niets in die trend wil, wordt het moeilijk denk ik.

[ Voor 61% gewijzigd door Anoniem: 135134 op 07-07-2006 17:07 ]


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 08:36
Kijk eens naar PHP's functies voor programma uitvoer
Met oa. exec() kun je gebruik maken van 'fc' op de command.

Acties:
  • 0 Henk 'm!

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 13-06 10:21
volgens mij wil TS niet alleen weten of de files hetzelfde zijn, maar juist wat de verschillen zijn

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
plakbandrol schreef op vrijdag 07 juli 2006 @ 17:21:
volgens mij wil TS niet alleen weten of de files hetzelfde zijn, maar juist wat de verschillen zijn
als dat zo is kan hij waarschijnlijk nog steeds linux tools gebruiken, maar mocht hij het in php willen doen:

gewoon loopje doen die door allebij de files tegelijk heen loopt.
wat je doet is het volgende:

1 je leest van bijde files 1 regel
2 die vergleijk je, als ze gelijk zijn doe je dit gewoon nog een keer etc.
3 als ze niet gelijk zijn doe je het volgende:
4 de regel van bestand 2 is 'fout', 'extra' of iig 'anders'
5 lees een nieuwe regel van bestand 2
6 vergelijk die met de regel van de eerste
7 als ze ongelijk zijn ga je naar stap 4

stel dat dit je bestanden zijn:
file 1
hoi
ik ben 
BasieP
ofzo


file 1
hoi
ik ben 
Erica
Terpstra
ofzo

je output is dan:
Erica
Terpstra

[ Voor 14% gewijzigd door BasieP op 07-07-2006 17:32 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

Anoniem: 128202

Topicstarter
Mijn bestanden bestaan uit 29 000 regels, en ik wil NIET bij elke regel uit tekst 1 ALLE regels nalopen uit tekst 2 om te kijken of er een dezelfde regel in tekst 2 voorkomt (ze zijn aangegeven met id's). (Ook elke regel nalopen uit tekst 2 om te kijken of het hetzelfde regelnummer heeft als tekst 1 en dan vergelijken duurt veel telang).
Maar hoe kan je nou juist zeggen "ga naar regel 15 000" zonder alle 14 999 regels die ervoor komen
over te slaan en dus niet uit te lezen??

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 04-07 15:03

NMe

Quia Ego Sic Dico.

Anoniem: 128202 schreef op vrijdag 07 juli 2006 @ 19:42:
Mijn bestanden bestaan uit 29 000 regels, en ik wil NIET bij elke regel uit tekst 1 ALLE regels nalopen uit tekst 2 om te kijken of er een dezelfde regel in tekst 2 voorkomt
Wat denk je dat fc intern doet? ;) (Al zal dat natuurlijk wat optimalisatieslagen hebben.)
Maar hoe kan je nou juist zeggen "ga naar regel 15 000" zonder alle 14 999 regels die ervoor komen
over te slaan en dus niet uit te lezen??
Niet. Je zal toch echt moeten lezen. Als je precies weet na hoeveel bytes de 15.000e regel begint kun je fseek gebruiken, maar anders zul je iets moeten doen als dit:
PHP:
1
2
for ($i = 0; $i < 14999; $i++)
  fgets($filePointer);

Overigens zie ik niet wat dat met het probleem in je topicstart te maken heeft?

[ Voor 4% gewijzigd door NMe op 07-07-2006 19:49 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 13-06 10:21
als hij het bestand per regel vergelijkt, en je neemt twee identieke bestanden waarbij je bij het ene bestand een witregel aan het begin zet, dan matched geen enkele regel meer, waardoor hij denkt dat het bestand 100% anders is..

lijkt me niet handig

Acties:
  • 0 Henk 'm!

  • pimlie
  • Registratie: November 2000
  • Laatst online: 05-07 18:29
Als je de gegevens per regel gaat bekijken, waarom dan niet zo:

PHP:
1
2
3
4
5
6
7
$f1 = file("bestand1.txt");
$f2 = file("bestand2.txt");

$a1 = array_diff($f1, $f2); // regels uit f1 die niet in f2 zitten
$a2 = array_diff($f2, $f1); // regels uit f2 die niet in f1 zitten

$a3 = array_merge($a1, $a2);


Geen idee of dit een beetje performed met grote array's maar wellicht een optie. Of moet je ook weten welke regelnummers verschillend zijn? (kan je natuurlijk ook wel weer achterkomen)

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Anoniem: 128202 schreef op vrijdag 07 juli 2006 @ 19:42:
Mijn bestanden bestaan uit 29 000 regels, en ik wil NIET bij elke regel uit tekst 1 ALLE regels nalopen uit tekst 2 om te kijken of er een dezelfde regel in tekst 2 voorkomt (ze zijn aangegeven met id's). (Ook elke regel nalopen uit tekst 2 om te kijken of het hetzelfde regelnummer heeft als tekst 1 en dan vergelijken duurt veel telang).
Maar hoe kan je nou juist zeggen "ga naar regel 15 000" zonder alle 14 999 regels die ervoor komen
over te slaan en dus niet uit te lezen??
volgens mij snap je mijn oplossing niet. deze is sequentieel, en je loopt dus 1x door beide files heen, in 1 loop. dwz, je itereert zo vaak als je regels hebt in je grootste bestand

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

Anoniem: 14124

Kun je niet het levensthein algoritme gebruiken om dan een diff te doen van twee bestanden en zo de verschillen te extraheren?

Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Laatst online: 14:48
plakbandrol schreef op vrijdag 07 juli 2006 @ 19:57:
als hij het bestand per regel vergelijkt, en je neemt twee identieke bestanden waarbij je bij het ene bestand een witregel aan het begin zet, dan matched geen enkele regel meer, waardoor hij denkt dat het bestand 100% anders is..
http://www.php.net/manual/en/function.trim.php

Acties:
  • 0 Henk 'm!

  • plakbandrol
  • Registratie: Juni 2002
  • Laatst online: 13-06 10:21
die witregel kan ook een willekeurige andere tekst zijn natuurlijk.. dan werkt trim niet

[ Voor 5% gewijzigd door plakbandrol op 07-07-2006 23:19 ]


Acties:
  • 0 Henk 'm!

Anoniem: 128202

Topicstarter
Beste pimlie,

Bedankt voor jouw reactie!!!! Het werkt perfect!!!!! En nog redelijk snel ook!!!! :*) _/-\o_

Acties:
  • 0 Henk 'm!

  • MissingDog
  • Registratie: Augustus 2002
  • Niet online
Check PEAR eens voor de Text_Diff API, doet ook wat jij wilt volgens mij en is door heel veel mensen getest/geimplementeerd inmiddels...vast een bruikbaar speeltje.

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Anoniem: 128202 schreef op maandag 10 juli 2006 @ 13:37:
Beste pimlie,

Bedankt voor jouw reactie!!!! Het werkt perfect!!!!! En nog redelijk snel ook!!!! :*) _/-\o_
Euhm nee.

De bestanden:

code:
1
2
3
1
2
3

en:

code:
1
2
3
3
2
1


Ziet array_diff als hetzelfde als ik me niet vergis.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info

Pagina: 1