Portál AbcLinuxu, 29. května 2024 18:33
Priezvisko; Meno; Ulica; Mesto; PSC; Telefon; TovarJa ale ešte musím nájsť duplicitné záznamy a jediným relevantným "ID" je pre mňa v tomto prípade telefónne číslo, ktoré ale nemusí byť pre konkrétny záznam len jedno (može byť napríklad aj: 0905123456,02/123456) a v prípade, že sa nachádza v tom csv viacero záznamov s rovnakým číslom, tak mám všetky záznamy pre tovar zlúčiť do jedného záznamu. Na serveri môžem použiť len php alebo shell, tak som si napísal php skript, ktorý ale v časti ktorá vyhľadáva duplicity trvá pri 50.000 záznamoch cca hodinu. Dotyčná časť je v priloženom súbore. V princípe tam ide o to, že do premennej Pole_1 si načítam ten csv, potom čítam v cykle položku po položke a porovnávam s vytváraným polom Pole_2. Ak sa dotyčný záznam v poli nachádza, tak len do stĺpca VydanyTovar pridám tovar z aktuálneho záznamu a ak sa nenachádza, tak pridám celý záznam. Príklad csv:
NezaujimavyBalast; Telefon; Tovar xxx ; 123 ; a xxx ; 567 ; b xxx ; 123,567; c xxx ; 567 ; dvýsledok je teda:
NezaujimavyBalast; Telefon; Tovar xxx ; 123 ; a c xxx ; 567 ; b dSamozrejme, že ten skript nie je dokonalý lebo ideálny výsledok by mal byť takýto (ale nato ako to mám zrobiť som už neprišiel):
NezaujimavyBalast; Telefon; Tovar xxx ; 123,567; a b c dNájde sa prosím vás nejaká dobrá duša čo mi s tým pomôže? Vopred vám veľmi pekne ďakujem.
xxx ; 123 ; a c xxx ; 567 ; b c d? Takýto druh výstupu by som získal jednoducho tak, že by som každý riadok, ktorý má N telefónnych čísiel nahradil N-ticou riadkov, z ktorých každý by mal len jedno číslo. Potom by som urobil mapu, kde by telefónne číslo bolo kľúčom a hodnotou by bol zoznam tovarov. Tú druhý variantu výstupu by som riešil tak, že by som vstup najprv utriedil tak, aby najprv boli záznamy s väčším počtom telefónnych čísiel. No a potom nejako dosiahnuť, aby kľúčom do spomínanej mapy nebolo jedno telefónne číslo ale množina čísiel a mapa vracala hodnotu nie ak je dané číslo kľúčom, ale ak kľúč (množina) obsahuje hľadané číslo. Žiaľ ako konkrétne to spraviť v PHP ti neporadím. To prenechám niekomu, kto vidí PHP častejšie, ako ja - raz za uhorský rok. V jave alebo C++ by sa to riešilo overloadnutím triedy implementujúcej mapu.
Pole_2
Potom misto linearniho prochazeni toho pole se jenom podivej jestli zaznam je v te tabulce. A jses na linearni slozitosti...
btw. 50 000 zaznamu za hodinu, to ne neuveritelne pomaly... Zpracovat takovy maly mnozstvi dat by melo trvat zlomky sekundy
Pokud to setridite, pak je mozne dosahnout podobneho vysledku, jaky popisujete v dotazu, jednim pruchodem dat.
viz:
echo 'xxx ; 123 ; a xxx ; 567 ; b xxx ; 123,567; c xxx ; 567 ; d' | sort -t ';' -k 2 | awk -F ";" '// {prvni=$2;sub(",.*","",prvni);sub("^ *","",prvni);sub(" *$","",prvni);if (zminula != prvni){if(telefon != "" ){print balast ";" telefon ";" tovar}; balast=$1;tovar=$3;zminula=$2;sub("^ *","",zminula);sub(" *$","",zminula);telefon=zminula}else{tovar= tovar $3; balast= $1;sub(" *$","",$2);sub("^ *","",$2); if (!match(","telefon",",","$2",")){ telefon= $2}}} END {print balast ";" telefon ";" tovar}'
To awk porovnava vzdy jenom s nasledujici polozkou v seznamu.
Verim ze s 50000 zaznamy to na dnesnim zeleze bude hotove velmi rychle
marekTiskni Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.