3 vagy tobb oszlop rendezese linux alatt

Fórumok

Sziasztok,

harom vagy tobb oszlopot szeretnek rendezni a kovetkezokeppen linux alatt.

Pelda:

Rendezes elott:

1 6 12
3 7 4
4 4 2
2 9  

Rendezes utan:

1 x1 x1
2 x2 2
3 x3 x3
4 4 4
x6 6 x6
x7 7 x7
x9 9 x9
x12 x12

12

 Megjegyzes: az x csupan azt jelzi, hogy az adott oszlopban nem szerepel - lehet helyette szinesen is jelezni, hogy hianyzik.

Talalkozott mar valaki hasonlo problemaval?

Koszonom elore a segitseget.

Ardi

Hozzászólások

Szerkesztve: 2023. 02. 14., k – 09:04

Hasonlo jellegu problemakkal mar tobbszor, ilyennel konkretan meg nem. De egy hulye megoldas lehet ez:

cat x.in | \
awk '{ for ( i=1;i<=NF; i++ ) print $(i),i; }' | \
sort -n | \
awk -v l=0 -v j=0 -v ncol=3 \
  '{    c=$1;i=$2;
        if ( c != p && 0<l ) 
         {   for(;j<ncol;j++)  printf(" -");
             printf("\n");
             j=0; 
         } 
        while ( j+1<i ) 
         {   printf(" -"); 
             j++; 
         }
        printf(" %s",c); 
        l++;
        p=c;
        j=i; 
  } \
 END \
  {     for(;j<ncol;j++)  printf(" -");
        printf("\n"); 
  }' > x.out

$ cat x.in
1       6       12
3       7       4
4       4       2
2       9
$ cat x.out
 1 - -
 2 - 2
 3 - -
 4 4 4
 - 6 -
 - 7 -
 - 9 -
 - - 12

Azt sajnos tudnod kell viszonylag hamar hogy hany oszlopod is van a bemenetben (lasd: ncol=3), mertkulonben a - jelekkel (hianyzo oszlopokkal) valo feltoltes nem fog menni...

Nem a legszebb, de pipeline-szeruen felepitheto, a nagy memoraigenyu reszt kiszervezed (`sort -n`) es csak az elozo sor allapotat kell letarolnod valahogy okosan/ugyesen. Szoval az a bonyolultnak latszo `awk` valojaban O(1) memoriaigenyu es O(n) futasi idovel rendelkezik, ami jo.

Szerkesztve: 2023. 02. 14., k – 11:12

Jól megválasztott asszociatív tömbbel szerintem megy az egyben is - ha sikerülne megérteni, pontosan mit is szeretnél...
 

Nem kell előre semmit sem rendezgetni - miután megértettem, mit kell kiírni a végén, már adódott a megoldás:

 

BEGIN { cmax=0; }
      { if ( cmax<NF ) { 
          cmax=NF; 
        };  
        for ( i=1; i<=NF; i++ ) {
          ertekek[$i]++;
          ertcol[$i"."i]++;
        }
      }
END   { for ( v in ertekek ) {
          for ( col=1; col<cmax+1; col++ ) {
            if ( ertcol[v"."col]==0 ) {
              p="-";
            } else {
              p=v;
            };
            printf "%s\t", p;
          };
          printf "\n" 
        }
      }

Igenigen, ez is fasza megoldas, csak nem tudtam hogy a kerdezo kolleganak mekkora az adatkupaca amit igy rendezgetni akar :) Ha tul nagy es/vagy maga a matrix tul ritka akkor ennek a megoldasnak tul nagy lehet a memoriafootprintje. Amit igy desszertnek maga az indexeles stukturaja ugyanakkora mertekben megdob, mint maga a rendezendo adat. 

Csak azert teteleztem fel ezt es azert kerestem O(1) megoldast mert mikor nekem voltak-vannak latszolag es/vagy egeszen hasonlo jellegu problemaim, akkor azok altalaban sokszor 10 vagy akar 100+ giganyi adat formajaban jelennek meg :)

ha alaposabban megnézed, a tied is csinál érték-oszlop "tömböt", amit te a sort-nak adsz oda - azaz annak teljes egészében elő kell állnia, hogy a sort végezni tudjon vele - utána awk-ban ezzel bűvészkedsz :)
A ritka mátrix miatt kifejezetten jó a "jól irányzott" (az index a mátrix koordinátájára mutat) asszociatív tömb, mert ott a "nincs olyan elem" az nem foglal helyet, csak az, amibe már raktam valamit. (Azaz egy 100*100-as egységmátrix ilyen leképezése pontosan 100 elemű asszociatív tömböt fog eredményezni - ami "nincs" (nincs a adott indexű eleme), az stringként üres stringet ad vissza, számként meg nullát. Próbáld ki: echo | awk '{i="foo"; printf "s:%s,\td:%d\n", nincs[i], nincs[i] }' )

Ja, és még egy apróság: ebben a megoldásban nincs megkötés az oszlopok számára, de az értékkészletre sem. (oké, ez utóbbi a sort mögötti "-n" elhagyásával megoldható...)

ha alaposabban megnézed, a tied is csinál érték-oszlop "tömböt", amit te a sort-nak adsz oda - azaz annak teljes egészében elő kell állnia, hogy a sort végezni tudjon vele

Igen, ez igaz. Ott annyi volt a gondolat hogy a `sort`-nal jobban/hatekonyabban vsz ugysem tudjuk igy egy ilyen "jaj, irjunk valamit gyorsan" jelleggel megirni :) Aztan hogy a `sort` maga hogy kezeli le a dolgot az mar az o baja... :) Annyi nyereseg lehet ottan hogy egyreszt a matrix ritkasaga miatt nem fog ottan noni a meret, masreszt nem kell kulon indexet fenntartanod. Es lehet hogy a gyakorlatban ezzel is sokat nyerhetunk mar. 

Mellesleg mivel az index és az érték azonos is lehetne, így lehetne bool type is a két dimenziós tömb.

En csupan tobb (~5-6) szerveren levo rpm csomagokat szeretnek hasonlitani.

Persze masra is jo lesz. :-)

 

Ardi

Csomaglisták összehasonlítására a diff parancsot lehetne használni. Begyűjteném a hostokról a listákat, majd mehetne egy diff.

Ebből egy csomaglista kéne, amit egy automatizáló eszköz (Ansible, Puppet, Salt etc.) tartana karban. Könnyebb lenne karbantartani is a későbbiekben.

Hat akkor ehhez lehet en ansible-t hasznalnek. csinalnek mindegyikrol egy list of maps-ot {host: verzio, csomagnev: blablah }-kent es aztan mehet ra a  community.general.lists_mergeby filter by csomagnev az osszes list-re. Igy a vegen megkapod csomagnevenkent az osszes "host:verzio"-t

de en megatalkodott vagyok :)