Ol�,

J� tentei solu��es como as dadas pelo Tiago, mas tinha muito que eu queria personalizar, ent�o h� muito tempo atr�s fiz um programa em C que segue no corpo da mensagem. Copie e cole em um editor, tipo o kwrite, salve como colunador.c, compile com "$ gcc colunador.c -o colunador" e execute com "$ ./colunador entrada.txt saida.txt". D� uma olhada na documenta��ozinha que fiz e ver� que este programa pode ajudar bastante.

[]'s

Claudio



/************************************************************
* Programa: colunador.c                                    *
*    Autor: Claudio Polegato Junior                        *
*     Data: 14/08/2001                                     *
*                                                          *
* Copyright (C) 2001 por Claudio Polegato Junior           *
* Todos os direitos reservados                             *
************************************************************/

/************************************************************
* Descri��o                                                *
*                                                          *
*     Programa para trabalhar com as colunas de um arquivo *
* texto utilizando-se de colunas com v�rios delimitadores  *
* e envolvedores de texto na coluna. Cada delimitador      *
* separa uma coluna da outra e cada linha da entrada deve  *
* terminar por \n (nova linha).                            *
*     Este programa requer uma arquivo de entrada (onde -  *
* especifica stdin, que � a entrada padr�o) e um arquivo   *
* de sa�da (onde - especifica stdout, que � a sa�da        *
* padr�o). Seguido destes par�metros obrigat�rios, tem-se  *
* os opcionais que s�o cada coluna a ser colocada na sa�da *
* do programa. Caso n�o seja fornecidad nenhuma coluna,    *
* inverte a ordem de todas as colunas encontradas na       *
* linha.                                                   *
*     Os envolvedores de texto s�o validados quando o      *
* primeiro caracter de uma coluna inicia por ele e o texto *
* desta coluna vai at� encontrar o caracter correspondente *
* ao envolvedor final, notado que cada envolvedor inicial  *
* tem um envolvedor final n�o necessariamente igual ao     *
* inicial. O texto depois do envolvedor final � ignorado e *
* o este texto engloba qualquer caracter que n�o seja o    *
* envolvedor final, inclusive o caracter de nova linha e   *
* separadores de coluna.                                   *
*     Existem algumas personaliza��es (at� estou pensando  *
* em colocar um arquivo de configura��o, por exemplo) que  *
* podem ser feitas alterando as constantes abaixo. Est�    *
* bem explicado o significado de cada uma e pode ser usada *
* a crit�rio das necessidades do momento.                  *
************************************************************/

// Defina aqui o separador de colunas na sa�da
// Para manter o mesmo da entrada, deixe-o com '\0'
const char Separador_Saida = ';';
// Defina aqui o envolvedor de texto da coluna na sa�da (inicial e final)
// Para manter os mesmos da entrada use '\0' e para desaparecer com eles use '\b'
const char Envoltor_Saida = '"';
const char Envoltor_Fim_Saida = '"';
// Caracteres delimitadores de Coluna
// O espa�o (' ') � interessante para arquivos com colunas que n�o contenham espa�os
// ou cada uma sempre entre aspas
const char Delimitadores[] = {',', ';', '\t', ' '};
// Caracteres que envolvem um texto completo
const char Envolvedores[] = {'"', '\'', '(', '[', '{', '<'};
const char Envolvedores_Fim[] = {'"', '\'', ')', ']', '}', '>'};



#include <stdio.h> #include <errno.h> #include <string.h> #include <locale.h>

int Nao_Delimitador(char c){
 int i = 0;
 while (c != Delimitadores[i] && ++i < sizeof(Delimitadores));
 return (i == sizeof(Delimitadores));
}

int Envolvedor(char c){
 int i = 0;
 while (c != Envolvedores[i] && ++i < sizeof(Envolvedores));
 if (i == sizeof(Envolvedores))
   i = -1;
 return i;
}

int main(int argc, char* argv[]){
FILE *Original, *Saida;
int Tamanho, Env, Indice_Coluna;
char *Conteudo, *c, *Coluna[1024];
char Separador[1024];
// Define localiza��o
setlocale(LC_ALL, "");
// Se n�o dados pelo menos o nome do arquivo original e o de sa�da, sai mostrando a forma de uso
if (argc < 3){
fprintf(stderr, "\nUso: %s <arquivo original> <arquivo invertido> [1� Coluna [2� Coluna [...]]]", *argv);
fprintf(stderr, "\n Caso n�o seja informada a ordem das colunas, inverte a ordem.\n\n");
return -1;
}
// Abre o arquivo original e retorna o erro se n�o conseguir
if (strcmp(argv[1], "-")){
Original = fopen(argv[1], "r");
if (! Original){
fprintf(stderr, "\nN�o foi poss�vel ler %s: %s\n\n", argv[1], strerror(errno));
return errno;
}
}
else
Original = stdin;
// Abre e zera ou cria o arquivo de sa�da e retorna o erro se n�o conseguir
if (strcmp(argv[2], "-")){
Saida = fopen(argv[2], "w");
if (! Saida){
fclose(Original);
fprintf(stderr, "\nN�o � poss�vel gravar em %s: %s\n\n", argv[1], strerror(errno));
return errno;
}
}
else
Saida = stdout;
// Tamanho do arquivo original
fseek(Original, 0, SEEK_END);
Tamanho = ftell(Original);
fseek(Original, 0, SEEK_SET);
// Coloca o conte�do do arquivo na mem�ria e fecha o mesmo
Conteudo = (char*)malloc(Tamanho+1);
fread(Conteudo, Tamanho, 1, Original);
Conteudo[Tamanho] = '\0';
fclose(Original);
// Marca as colunas da linha atual separando-as por \0
c = Conteudo;
Indice_Coluna = 0;
while (*c){
Coluna[Indice_Coluna] = c;
if ((Env=Envolvedor(*c)) > -1){
if (Envoltor_Saida == '\b')
Coluna[Indice_Coluna]++;
else if (Envoltor_Saida)
*c = Envoltor_Saida;
c++;
while (*c && *c != Envolvedores_Fim[Env])
c++;
if (Envoltor_Saida == '\b')
*(c++) = '\0';
else if (Envoltor_Saida)
*(c++) = Envoltor_Saida;
}
while (*c && *c != '\n' && Nao_Delimitador(*c))
c++;
if (!*c || *c == '\n'){ // Fim da linha
int i;
*(c++) = '\0';
if (argc == 3){
for (i=Indice_Coluna; i>0; i--){
if (Separador_Saida)
fprintf(Saida, "%s%c", Coluna[i], Separador_Saida);
else
fprintf(Saida, "%s%c", Coluna[i], Separador[i]);
}
fprintf(Saida, "%s\n", Coluna[0]);
}
else{
int Coluna_Atual;
for (i=3; i<argc-1; i++){
Coluna_Atual = atoi(argv[i])-1;
if (Coluna_Atual > Indice_Coluna){
if (Separador_Saida)
fprintf(Saida, "%c", Separador_Saida);
else
fprintf(Saida, "%c", Separador[i]);
}
else{
if (Separador_Saida)
fprintf(Saida, "%s%c", Coluna[Coluna_Atual], Separador_Saida);
else
fprintf(Saida, "%s%c", Coluna[Coluna_Atual], Separador[i]);
}
}
Coluna_Atual = atoi(argv[argc-1])-1;
if (Coluna_Atual <= Indice_Coluna)
fprintf(Saida, "%s\n", Coluna[Coluna_Atual]);
else
fprintf(Saida, "\n");
}
Indice_Coluna = 0;
}
else{ // Delimitador
Separador[Indice_Coluna] = *c;
*(c++) = '\0';
Indice_Coluna++;
}
}
fclose(Saida);
return 0;
}


---------------------------------------------------------------------------
Esta lista � patrocinada pela Conectiva S.A. Visite http://www.conectiva.com.br

Arquivo: http://bazar2.conectiva.com.br/mailman/listinfo/linux-br
Regras de utiliza��o da lista: http://linux-br.conectiva.com.br
FAQ: http://www.zago.eti.br/menu.html

Responder a