keresés gz file-okban

Szeretnék keresni sok nagy gz file-ban egy php-ban. Eddig az exec tünt a legegyszerűbb megoldásnak egy zcat segítségével, de ez kicsit lassúnak tűnik, az is :)
Hogy tudnám ezt más alapokra helyezni, esetleg több egyidejű szálon keresni a file-okban?

Vagy van erre valami bevált megoldás?

Hozzászólások

Rengeteg bevált megoldás van.

A spektrum a több vagy gyorsabb hardver alkalmazásától az előfeldolgozáson át (lusta végrehajtás, gyorstárazás, indexelés), a tömörített szövegben keresni képes algoritmusok (lzgrep) alkalmazásáig terjed.

Részletgazdag probléma leírás nélkül nem lehet ezek közül választani.

igazából ezek log file-ok, melyekben minden mezőt szaparátor választ el. elég nagy file-ok, így az egész membe olvasása teljesen felesleges.
Egyez mezők értékeire lenne feltétel megadva, ami alapján kéne szűrni. A végeredményt szöveges vagy tömbös formában képzeltem el, amit egyszerűen lehetne egy táblázatban megjeleníteni.
minden nap keletkezik egy ilyen gz file és a megadott napokra, időszakra (ez végül is már a témától független) kéne több file-ban keresni.

utánna nézek, amit írtál

> igazából ezek log file-ok,

Ez kizárja a "lusta végrehajtás"-t. Ha jórészt egy felhasználó érdekében kell csak keresni, akkor nincs értelme összevárni kereséseket.

> Egyes mezők értékeire lenne feltétel megadva, ami alapján kéne szűrni.

Nem mindegy hogy mennyit lehet előre tudni ezekről a feltételekről. Előre nem ismert lekérdezések végrehajtására az SQL egy kényelmes eszköz, a log-ok ezek szerint mehetnének valami adatbázisba (indexelés). Előre ismert lekérdezések eredményeit pedig a gz fájlok keletkezésekor le lehetne generálni (gyorstárazás).

> előre nem ismert a feltétel, mert azt a felhasználó adja meg

Akkor ki kellene kérdezni a felhasználót, hogy mire használja fel az adatokat. Például minden reggel megnézi, hogy X, majd ha azt látja hogy Y, akkor megnézi még azt is hogy Z. Szóval előfordulhat, hogy a felhasználónak vannak gyakran használt "forgató könyvei". Rendszeresen összeállít valami jelentést, kvótát ellenőriz, stb.

> a log file-ban van, minek töltsem sql-be,

Azt írtad: "kicsit lassú"; ha nem változtatsz semmin, akkor ugyanilyen lassú marad.

mivel a file adott, és nem igazán szeretném többször tárolni, mert pár 10 G méretű, így nem tudom, hogy tudnék előre definiált feltételeket gyártani.
igazából 2 részre keresnek rá, de azon belül bármire, teljes kifejezéssel, vagy rész kifejezéssel.
egy megoldást látok a sebesség növelésére, ez pedig a párhuzamos file feldolgozás lenne. de ez nem tudom mennyire kivitelezhető php-ban. még arra is gondoltam, hogy egy tmp file-ba írom bele az eredményt, vagy többe, és akkor ezeket felolvasom.

> igazából 2 részre keresnek rá

A "pár 10G" méretnek hány %-át érinti ez a "2 rész"? Nyilván ha 98%, akkor az más eset, mint ha 2%.

> ez pedig a párhuzamos file feldolgozás lenne.

Ha a lassúság a diszk IO lassúságához kötődik, akkor a párhuzamos feldolgozás (több hardver igénybevétele) nem segít.

Tudsz gyerek processeket gyartani.
http://hu2.php.net/pcntl_fork
( http://code.google.com/p/php-pthreads/ )

Vagy hasznalhatsz C kodot, amit php -bol hivsz ami esetleg szalakat is hasznalhat, ha az szimpatikusabb.
Ha regexp-et hasznlasz vigyaz arra, hogy a megoldasod ne forditsa mindig ujra regexpet, ha a feladat egyszerubben megoldhato regexp nelkul is, akkor C.

Amit nem lehet megirni assemblyben, azt nem lehet megirni.

php-nek van zlib és bzip2 libje is, így nem kell system-et hívnod. Aztán lehet használni a megfelelő read (bzread) függvényt.
Persze a sorokban neked kell már keresned regexp-el vagy valamivel.

találtam egy egyszerű megoldást, ami talán lehedi az én szükségeimet.
ez a legkevesebb fejlesztést igényli tőlem most.
ami nem állna másból mint az elején említett exec-et.
lenne egy pl. exec("zgrep mit hol1 & zgrep mit hol2 & zgrep mit hol3 .....", $out);
így az op elvégzi helyettem az összes feladatot, és azt kapom amit szerettem volna.
az eredményt már kezelhetem bárhol.

A probléma helyes megfogalmazásával kezdeném... A tömörített szövegfájl helykihasználásra van optimalizálva, neked viszont keresésre kell optimális(hoz közeli) állapotot létrehozni. Minden egyes lekérdezésnél kicsomagolni, szekvenciálisan végigmenni... Sem nem optimális, sem nem szép, radásul erőforrás-zabáló is. (Csak egy közbevetett kérdés: időintervallumot pl. regexp-pel hogy írsz le, hogy gyorsan és pontosan működjön?)

Ami korábban is volt, hogy valamilyen sql-lel kérdezgethető adatbázisba raknám értelmesen a logot (ami pl. időpont benne, azt dátumként, ami szám, azt numerikus mezőbe, sőt a log tartalmi részét is megpróbálnám valamilyen módon normalizálni a betöltés során), és onnan egyszerű select... from ... where ... módszerrel szedném ki a releváns adatokat.

Esetleg meg lehet próbálni valamilyen indexelő eszközzel a sima szöveges fájlt megetetni, és ebben az adathalmazban keresni. (Webes tartalomra pl. ott van a phpdig...).