• Publicidad

Aplicar split en array con ciertas condiciones

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Aplicar split en array con ciertas condiciones

Notapor sisifo80 » 2015-10-24 03:58 @207

Hola.

Tengo una entrada con el siguiente formato:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
texto
texto
...
(ID 3467)

texto
texto
...
(ID 3467)

texto
texto
...
(ID 5993)
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Es decir: Tengo un conjunto variable de líneas de texto cuya última línea es un código entre paréntesis, y después otro conjunto variable de líneas de texto cuya última línea es un código -y aquí viene mi complicación- que puede ser o no el mismo código que el anterior, y así sucesivamente...

Necesito un script que lea ese archivo y cree tantas carpetas como códigos diferentes existan (el nombre de cada carpeta será el propio código), y que dentro de cada carpeta cree un archivo (el nombre del archivo será también el propio código) en cuyo contenido se imprima la parte de texto de la entrada que corresponda a ese código.

Por ejemplo, siguiendo con el ejemplo anterior, debería obtener lo siguiente:

a) una carpeta llamada "3467" que contenga un archivo llamado "3467" cuyo contenido sea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
texto
texto
...
ID 3467

texto
texto
...
ID 3467
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


b) una carpeta llamada "5993" que contenga un archivo llamado "5993" cuyo contenido sea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
texto
texto
...
ID 5993
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Y así, sucesivamente.

Pues bien, yo llego hasta aquí:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $filename = shift;
  2. open F, $filename or die;
  3. undef $/;
  4. $file = <F>;
  5. close F;
  6.  
  7. @s = split /\(ID .*?\K\n/, $file;              # divido la entrada en partes siempre que encuentre la secuencia ID + cualquier cosa + cambio de línea
  8.  
  9. foreach $s (@s) {
  10.  
  11.     if ( $s =~ m/\ID (.*?)\)/ ) {              # capturo el código en una variable
  12.         $code = $1;
  13.     }
  14.  
  15.     mkdir "$code";                             # creo carpeta con el código
  16.                                                # creo archivo con el código
  17.     open FILE, '>', "$code/$code\.txt" || die "can't open file output/$code";
  18.     print FILE "$s";
  19.     close FILE;
  20.  
  21. }
  22.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Como veis, solo sé dividir la entrada en partes siendo cada parte un conjunto del tipo "texto, texto, text, ID código". Pero lo que quisiera, y no sé cómo, es que mi array tuviese en cuenta que si el código es igual al anterior no aplique la función split(), para dividir así el texto en las partes que realmente necesito.

No sé si me he explicado muy bien...
sisifo80
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2013-11-20 07:30 @354

Publicidad

Re: Aplicar split en array con ciertas condiciones

Notapor explorer » 2015-10-24 04:11 @216

Hay otra opción, muy buena: en lugar de dividir por el ID, hacerlo por la línea en blanco que le sigue.
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: Aplicar split en array con ciertas condiciones

Notapor sisifo80 » 2015-10-24 05:06 @254

Hola, explorer. Gracias por tu respuesta.

El problema es que la línea en blanco no es sistemática: podría aparecer o no. Lo único sistemático es la línea con el código después de cada conjunto de texto. Por otro lado, y suponiendo que la línea en blanco sí fuese sistemática, no entiendo cómo podría eso resolver mi problema, pues seguiría obteniendo divisiones inferiores a lo que yo necesito (a veces necesitaría que varias líneas en blanco se capturasen en la misma subdivisión y a veces no, puesto que el código que sigue a cada conjunto de texto a veces es igual al anterior y a veces no).
sisifo80
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2013-11-20 07:30 @354

Re: Aplicar split en array con ciertas condiciones

Notapor explorer » 2015-10-25 10:02 @459

Esta es una posible solución, aunque no acabo de entender el porqué hay que crear un subdirectorio con el nombre del ID, ya que solo con crear el archivo de basado en el ID, vale.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.18;
  3. use autodie;
  4. use File::Slurp;
  5.  
  6. my $archivo = read_file('code_39015.txt');
  7.  
  8. my %ids;                                        # base de datos
  9.  
  10. while ($archivo =~ /\G\s*(?<texto>.+?)\s*\(ID (?<id>\d+)\)/msg) {
  11.  
  12.     my($texto, $id) = @+{qw'texto id'};
  13.  
  14.     push @{ $ids{ $id } }, $texto;
  15. }
  16.  
  17. for my $id (keys %ids) {
  18.  
  19.     mkdir $id;
  20.    
  21.     write_file("$id/$id.txt", join("\n" => @{ $ids{$id} }) . "\nID $id\n");
  22. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Lo que hacemos es ir guardando en un hash de array todas las partes que siguen el patrón buscado.

Luego, solo queda recuperar los ID y generar la salida.
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: Aplicar split en array con ciertas condiciones

Notapor sisifo80 » 2015-10-27 02:44 @156

Muchas gracias, explorer.
sisifo80
Perlero nuevo
Perlero nuevo
 
Mensajes: 32
Registrado: 2013-11-20 07:30 @354


Volver a Intermedio

¿Quién está conectado?

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