• Publicidad

Función SPLIT en más de 2 millones de datos

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Función SPLIT en más de 2 millones de datos

Notapor Fernando_Frez_1 » 2014-06-03 16:42 @737

Estimados: Quisiera un poco de ayuda en el trabajo que estoy realizando, el cual consta de filtrar un archivo .txt, con más de 2 millones de datos que cuentan con la siguiente estructura:

(ID1,'TEXTO1','clasificacion1','user1','timestamp1','url1','código1),(ID2,'TEXTO2','clasificacion2','user2','timestamp2','url2','código2), ...

Dichos datos se encuentran almacenados en forma consecutiva separados tan solo por una coma ",", donde en ciertos sectores aparece un punto y coma ";".

De lo anterior, requiero generar un filtro mediante Perl para poder dejar tan solo los siguientes datos: ID, TEXTO, USER, y timestamp.

Por lo tanto, intenté realizarlo con la función split(). El problema es que dicha función me toma las primera 600 líneas y quizás más, formándome bloques de texto y no pudiendo evaluar línea por línea para por hacer el filtrado respectivo.

El código es el siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open FICHERO,"datos_2013.txt";
  2. open SALIDA,">salida.txt";
  3.  
  4.  
  5. while($linea = <FICHERO>) {
  6.  
  7.  
  8.         @cadena=split(/,/,$linea);
  9.         print SALIDA $cadena[0].",".$cadena[1].",".$cadena[3].",".$cadena[4].")"."\n";
  10. }
  11.  
  12. close FICHERO;
  13. close SALIDA;
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

Favor si me pudieran orientar para poder generar un filtrado eficiente para poder manipular los datos en forma individual desde una aplicación en Java.

Saludos :D
Última edición por explorer el 2014-06-03 18:01 @792, editado 1 vez en total
Razón: Poner marcasde código Perl
Fernando_Frez_1
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2014-06-03 16:28 @728

Publicidad

Re: Función SPLIT en más de 2 millones de datos

Notapor explorer » 2014-06-03 18:09 @798

Bienvenido a los foros de Perl en Español, Fernando_Frez_1.

No debes usar split(), porque la coma es también el delimitador entre campos de un registro.

Por el ejemplo, deducimos que los registros no están separados por avances de línea, si que están escritos de forma consecutiva. ¿Es así? ¿No hay caracteres de avance de línea?

Entonces, lo que hay que hacer es leer el archivo y, aplicando una expresión regular, extraer los registros delimitados por los paréntesis, y luego ya sí puedes aplicar el split() a cada registro.

Por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.14;
  3. #use autodie;
  4. #use File::Slurp;
  5.  
  6. #my $archivo = read_file('archivo.txt');
  7. my $archivo = q((ID1,'TEXTO1','clasificacion1','user1','timestamp1','url1','código1),(ID2,'TEXTO2','clasificacion2','user2','timestamp2','url2','código2),);
  8.  
  9. while ($archivo =~ /\( (.+?) \)/gx) {           # capturar repetidamente lo que está entre paréntesis
  10.  
  11.     my $registro = $1;                          # lo capturado
  12.  
  13.     my @campos = split /[,]/, $registro;        # lo partimos
  14.  
  15.     say "@campos";                              # y pintamos (por ejemplo)
  16. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Función SPLIT en más de 2 millones de datos

Notapor Fernando_Frez_1 » 2014-06-03 18:22 @807

Estimados: Muy agradecido por la bienvenida y pronta respuesta. Los registros están en forma consecutiva y no están separados por avances de línea. Para aclarar un poco más el tema los registros son tweets traspasados de una gran BD a un archivo de texto (aprox. 711 MB), y hay sectores donde me encuentro con sentencias SQL entremedio de los registros, lo cual me complica bastante, por ejemplo:

INSERT INTO `datos_2013` VALUES (1024766216,'Que lindo que es saber que la plata que nos saca el gobierno es para mantener a estos negros de mierda y no para educación, 'Sin clasificar','santigomez1')

Lo anterior es en respuesta al código que pegué anteriormente, por lo cual además de filtrar los registros dentro de los paréntesis que no requiero, debo filtrar estas instrucciones que están, en alguno sectores, entre registros.

Voy a probar su código y comento, agradezco su respuesta.

Saludos cordiales.
Fernando_Frez_1
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2014-06-03 16:28 @728

Re: Función SPLIT en más de 2 millones de datos

Notapor explorer » 2014-06-04 04:14 @218

Si las sentencias SQL son todas del mismo estilo (INSERT) entonces también se pueden filtrar, en caso de que no queramos quedarnos con su contenido, ya que veo que tienen un número de campos distinto al del resto de registros.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Función SPLIT en más de 2 millones de datos

Notapor Fernando_Frez_1 » 2014-06-10 11:03 @502

Estimado: Al querer filtrar desde mi archivo .txt, debo agregar la sentencia open FICHERO,"datos_2013", por ejemplo, para abrir el archivo en modo lectura, ya que en tu código tengo ciertas dudas como por ejemplo de la línea 3 a la 6 que están con "#", ¿esas debo dejarlas habilitadas (sin #) para que lean desde mi archivo de texto y poder filtrar los datos? ¿Será necesario el uso de un gestor de archivo?

De antemano, muchas gracias.
Fernando_Frez_1
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2014-06-03 16:28 @728

Re: Función SPLIT en más de 2 millones de datos

Notapor explorer » 2014-06-10 11:58 @540

Las líneas 3, 4 y 6 equivalen a la línea 7.

Es decir, en mi programa, en lugar de hacer la operación de lectura, la imito con la asignación de un texto directamente en la línea 7.

Entonces, lo que tienes que hacer es cambiar las líneas 3 a 7 (incluidas) con tu propio procedimiento para leer todo el archivo a una sola variable escalar.

O comentas o borras la línea 7 y descomentas las líneas 3 a 6, cambiando 'archivo.txt' por el nombre de tu propio archivo.

Naturalmente, necesitarás tener instalado el módulo File:Slurp, para que funcione, ya que usamos su método read_file().
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Función SPLIT en más de 2 millones de datos

Notapor Fernando_Frez_1 » 2014-06-15 14:27 @643

Muchas gracias, me ha funcionado muy bien. Ahora me encuentro trabajando la expresión para que considere paréntesis curvos dentro de lo leído, ya que en algunos casos me leía hasta la mitad ya que había por ejemplo algo así : "(?)" , provocando que le leyera hasta "(?" y todo lo demás quedaba desechado. ¡Saludos y muchas gracias! :D
Fernando_Frez_1
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2014-06-03 16:28 @728

Re: Función SPLIT en más de 2 millones de datos

Notapor Fernando_Frez_1 » 2014-06-15 18:46 @823

Llegué al siguiente código que me filtra paréntesis intermedios pero... no sigue con el siguiente grupo de campos...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while ($archivo =~ /\( (.+?) (\).+?) \)/gx) {           # capturar repetidamente lo que está entre paréntesis
  2.  
  3.     my $registro = $1;                                  # lo capturado
  4.     my $registro2= $2;
  5.     say SALIDA $registro.$registro2;
  6.     #say SALIDA "@campos";                              # y pintamos (por ejemplo)
  7.    
  8. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

¿Algún consejo? Saludos.
Fernando_Frez_1
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2014-06-03 16:28 @728

Re: Función SPLIT en más de 2 millones de datos

Notapor explorer » 2014-06-15 21:13 @926

Debes decirnos de forma mucho más detallada (mejor dicho, completa) cómo son los registros que quieres leer.

Si dices que tienes que capturar lo que está en paréntesis, pero a su vez ocurre que puede tener dentro más paréntesis, estamos en un problema clásico de interpretación de registros, que puede ser muy complicado, si no sigue una serie de reglas estrictas.

Hay módulos especializados en este tipo de problemas, como Text::CSV, que son capaces de detectar esos casos, pero antes queremos ver un ejemplo de todos los casos posibles: desde el más sencillo al más complicado.

O una descripción formal de cómo son los registros.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Función SPLIT en más de 2 millones de datos

Notapor Fernando_Frez_1 » 2014-06-16 14:35 @649

Estimado: Lamento la falta de información, aquí complemento mi pregunta:

Los tipos de registros son los siguientes:

ID: Tipo numérico entero, por lo general más grande que 1 000 000 000.

Texto: tipo cadena de caracteres alfanuméricos y con posibilidad de incluir cualquier tipo de carácter que nos proporciona el teclado. Éste es el texto que uno escribe en twitter (largo máximo 140 caracteres). Al ser un tweet re-tweeteado, en este texto aparecerá la cadena "RT", que es MUY importante para mí, ya que la usaré para distinguir los tweets que son respondidos y los que son retweeteados, con el fin de formar árboles de tweets para lograr una búsqueda eficiente. Es aquí donde existen la mayor cantidad de problemas para filtrar los datos, ya que como expliqué puede ir cualquier carácter provocando problemas con las expresión regular como lo son los "(" ")" dentro del texto, con la posibilidad de que sea más de una vez.

Clasificación: Cadena de caracteres que identifica el tipo de tweet, la gran mayoría son "Sin Clasificar".

User: Cadena de caracteres con el nombre del usuario que generó el tweet, puede contener cualquier carácter, al igual que el texto del tweet es altamente indispensable.

TimeStamp: Fecha y hora de ingreso al sistema del tweet, con el formato "aaaa-dd-mm hh:mm:ss".

URL: Dirección donde está alojado el tweet. Pueden aparecer todos los caracteres permitidos en una URL

Número del tema: Entero no superior a 1000, que indica el número del tema al que se refiere el tweet.

Cada tweet se compone de la siguiente forma:
(ID,'Texto','Clasificación','User','TimeStamp','URL',Número del tema)

Solo necesito los registros en AZUL. Para ello también debo filtrar las comillas simples " ' " para tratar cada registro en forma individual en una aplicación en Java. Es en esa aplicación donde ocupo la función Split para separarlos por la ",". Fijaros que ni ID ni número del tema llevan comillas simples.

El caso más fácil o feliz sería:
(1024775407,'No es la apariencia, es la esencia. No es el dinero, es la educación. No es la ropa, es la clase.','Sin clasificar','DarihoA','2013-04-05 04:02:43','https://twitter.com/190033321/status/320023668631666688',339)

El caso más difícil:

(1024775406,')RT @allendexxi: Bien la) aprobación de la acusación de (Beyer) pero no olvidamos ((q)) la Concertación también avaló el lucro en la educación!)','Sin clasificar','Mar_c(i)aVargasS','2013-04-05 04:02:45','https://twitter.com/66868014/status/320023679369113600',339)


Espero haber sido más completo en la información.


Saludos Cordiales.
Fernando_Frez_1
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2014-06-03 16:28 @728

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 16 invitados