Newsgroup: it.comp.programmare
Titolo: AIUTO

ciao qualcuno può aiutarmi?
avrei bisogno di manipolare un file testo nella seguente maniera:
il file è un log generato da una macchina proxy
è delimitato da virgole (vedi esempio in basso),
sono righe praticamente tutte uguali per quanto riguarda la
formattazione,
dovrei usare un batch, non posso usare excel in quanto il file cambia
di giorno in giorno ed è meglio evitare i "copia e incolla",
la formattazione deve rimanere invariata.
devo spostare una selezione della stringa in un altra posizione
definita sovrapponendo i dati presenti nella nuova posizione.
esempio:
la rappresentazione di cui sotto è copia fedele del log tranne che per
i contenuti.
i numeri della prima riga rappresentano le colonne, le altre righe
quelle in cui intendo fare la sostituzione.
____________________________________________________
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...n
,-,-,112,-,-,-,-,-,xxx.toto,-,-,-,-,-,-,
,-,-,134,-,-,-,-,-,xxx.pappa,-,-,-,-,-,-,
,-,-,10,-,-,-,-,-,xxx.pizza,-,-,-,-,-,-
,-,-,n,-,-,-,-,-,n,-,-,-,-,-,-,
-----------------------------------------------------
il risultato che vorrei ottenere è il seguente:
spostare la colonna "9", contenente "xxx.toto" nella colonna "3"
contenente "112" e cosi via come sotto, l'eliminazione della colonna
"3" non crea problemi
___________________________________________
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...n
,-,-,xxx.toto,-,-,-,-,-,-,-,-,-,-,-,
,-,-,xxx.pappa,-,-,-,-,-,-,-,-,-,-,-,
,-,-,xxx.pizza,-,-,-,-,-,-,-,-,-,-,-
,-,-,n,-,-,-,-,-,-,-,-,-,-,-,
____________________________________________

 č delimitato da virgole (vedi esempio in basso),
AWK dovrebbe fare al caso tuo.
http://www.gnu.org/software/gawk/manual/html_mono/gawk.html#Reading%20Files
Io non lo conosco granche', in alternativa un programmino "C" che
fa quello che chiedi non dovrebbe essere troppo complicato.
Se ti interessa...
C:\>iao Angelo
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 > è delimitato da virgole (vedi esempio in basso),


 posso usare awk, fammi sapere
awk e' disponibile anche per Windows :-)...
In ogni caso...
- Mediamente quanto e' grande il file di log?
- una riga termina con un a capo, o si estende
  per piu' linee del file?
- le righe hanno tutte lo stesso numero di campi?
- i campi hanno lunghezza costante (sembra di no, ma vorrei
  la conferma)?
- le righe hanno una lunghezza prefissata (sembra di no, ma
  vorrei la conferma)?
- la riga inizia con una virgola come nel post originale?
- dopo lo spostamento della colonna, fa niente se la riga
  e' un capo piu' corta o bisogna aggiungere un campo da
  qualche parte per mantenere il numero di campi originale?


...


 ok.. i file sono grandi mediamente 1700- 2000 kb,
Allora entrambi i programmi vanno bene
<CODE_1>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
   int   idx     = 0;
   int   commas  = 0;
   int   retVal  = 0;
   int   rowLen  = 0;
   char* memBlkP = NULL;
   char* startP  = NULL;
   char* endP    = NULL;
   char* curRowP = NULL;
   char* firstP  = NULL;
   char* secondP = NULL;
   char* thirdP  = NULL;
   char* restP   = NULL;
   FILE* inP = NULL;
   struct stat fileData;
   if(argc > 1)
   {
      retVal = stat(argv[1], &fileData);
      if(0 == retVal)
      {
         memBlkP = calloc(1, fileData.st_size +2);
         if(NULL != memBlkP)
         {
            inP = fopen(argv[1], "r");
            if(NULL != inP)
            {
               retVal = fread(memBlkP, 1, fileData.st_size, inP);
               if(fileData.st_size >= retVal)
               {
                  if('\n' != memBlkP[retVal -1])
                     memBlkP[retVal] = '\n';
                  fclose(inP);
               }
               else
                  exit(1);
            }
            else
               exit(1);
         }
         else
            exit(1);
      }
      else
         exit(1);
   // Elaborazione dati in memoria.
   // -----------------------------
      startP = memBlkP;
      endP = strchr(startP, '\n');
      while(0 != endP)
      {
      // calcolo lunghezza della riga
      // ----------------------------
         rowLen = endP - startP;
         if(1 < rowLen)
         {
            curRowP = calloc(1, rowLen +1);
            if(NULL != curRowP)
            {
               strncpy(curRowP, startP, rowLen);
            // Ricerca terza colonna.
            // ----------------------
               while(commas < 10 && '\0' != curRowP[idx])
               {
                  if(',' == curRowP[idx])
                  {
                     commas++;
                     switch(commas)
                     {
                        case 3  : curRowP[idx] = '\0';
                                  thirdP = curRowP +idx +1;
                                  break;
                        case 4  : curRowP[idx] = '\0';
                                  secondP = curRowP +idx +1;
                                  break;
                        case 9  : curRowP[idx] = '\0';
                                  firstP = curRowP +idx +1;
                                  break;
                        case 10 : curRowP[idx] = '\0';
                                  restP = curRowP +idx +1;
                                  break;
                        default : break;
                      }
                  }
                  idx++;
               }
            // Stampa della nuova riga.
            // ------------------------
               printf(curRowP);
               printf(",");
               printf(firstP);
               printf(",");
               printf(secondP);
               printf(",");
               printf(thirdP);
               printf(",");
               printf(restP);
               printf("\n");
               idx    = 0;
               commas = 0;
               free(curRowP);
            }
            else
               exit(1);
         }
         startP = endP +1;
         endP = strchr(startP, '\n');
      }
   }
  return 0;
}
</CODE_1>
<CODE_2>
%{
/*
 *
 * Generare il sorgente mediante
 *
 *    flex -ocolsexchanger.c colsexchanger.l
 *
 * e compilarlo come un qualsiasi altro sorgente "C".
 *
 */
#include <stdlib.h>
#include <string.h>
char* strP;
#define NTOKS       50
#define NFIELDS     16
#define FIELD      100
#define ROW_TERM   200
#define INSF_MEM   300
%}
%%
[^,\n]*,   {
              strP = strdup(yytext);
              return FIELD;
           }
\n       {
            return ROW_TERM;
         }
%%
int main(int argc , char* argv[])
{
   int     idx       = 0;
   int     retVal    = 1; // serve solo per entrare nel ciclo
   int     totFields = 0;
   int     maxFldNum = 0;
   char*   tmpStrP   = 0;
   char**  fieldsPP  = NULL;
   extern FILE* yyin;
   if(argc > 1)
   {
      yyin = fopen(argv[1], "r");
      if(NULL != yyin)
      {
      // Allocazione iniziale di NTOKS puntatori a char:
      // ogni puntatore conterra' l'indirizzo di uno dei
      // campi contenuti nella riga esaminata, o un
      // puntatore NULL se la stringa e' vuota
      // -----------------------------------------------
         while(0 < retVal)
         {
            if(totFields >= maxFldNum)
            {
               fieldsPP = realloc(fieldsPP,
sizeof(char*)*(maxFldNum+NTOKS));
               if(NULL != fieldsPP)
                  maxFldNum += NTOKS;
               else
                  exit(1);
            }
 
            retVal = yylex();
            switch(retVal)
            {
               case FIELD     : fieldsPP[totFields] = strP;
                                totFields++;
                                break;
               case ROW_TERM  : if(NFIELDS == totFields)
                                {
                                   idx = 0;
                                   tmpStrP = fieldsPP[3];
                                   fieldsPP[3] = fieldsPP[9];
                                   fieldsPP[9] = tmpStrP;
 
                                   while(idx < totFields)
                                   {
                                      printf(fieldsPP[idx]);
                                      free(fieldsPP[idx]);
                                      idx++;
                                   }
                                   printf("\n");
                                   totFields = 0;
                                }
                                break;
 
               default        : free(fieldsPP);
                                fclose(yyin);
                                break;
            }
         }
      }
      else
         exit(1);
   }
   else
      exit(1);
   return 0;
}
int yywrap(void)
{
   return 1;
}
</CODE_2>
Entrambi  i programmi  dovrebbero funzionare  (senza  troppe pretese),
entrambi hanno un  controllo degli errori praticamente nullo.  Se vuoi
un consiglio  procurati  flex e  compilati  CODE_2. In alternativa, se
l'indirizzo di e-mail e' buono, te lo spedisco...
Il fatto che i programmi scrivano su stdout, non e' un grosso problema
nomePrg inFile > outFile
e passa la paura :-)
HTH
