• Publicidad

Eliminar frases desde una palabra clave hasta otra

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

Eliminar frases desde una palabra clave hasta otra

Notapor gandalfalexgan » 2010-07-08 04:12 @216

Hola,

Primeramente felicitar a los usuarios de este foro, siempre os he utilizado como guía de referencia y recomendado para consulta de dudas.

Bueno, mi problema es el siguiente: soy administrador de sistemas junior, y me han encomendado utilizar Perl para "depurar un fichero"; este fichero tiene unas 60 mil líneas, exactamente es un export de Oracle. A continuación os muestro algunas líneas de este código:

REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_INSTALACION"
REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGUO"
REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" DATE,
REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
REM STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1) TABLESPACE
REM "ABA_DATA" NOLOGGING NOCOMPRESS ;
~


Lo que tengo que hacer es crear un script que elimine del fichero, la frase azul tantas veces como aparezca. El único patrón que hay es la primera palabra: STORAGE(INITIAL, y la última palabra: 1). Éstas no siempre están en la misma línea. El resto de palabras que hay en el medio varían, por lo que me he visto obligado a pasar de SED y utilizar Perl.

No soy ningún experto en Perl. He hecho el script como lo hubiera hecho en C, tal vez ahí el problema. A continuación os muestro mi script.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. $storage="STORAGE(INITIAL";
  3. $fin="/)";
  4. $s=0;
  5. $fichero=shift;
  6. open FICHERO, $fichero or die "ERROR: No encuentro el fichero texto.txt\n";
  7. @lineas = <FICHERO>    or die "ERROR: No puedo leer el fichero\n";
  8. close FICHERO          or die "ERROR: No puedo cerrar el fichero\n";
  9. for ($i=0; $i <= @palabras; $i++){
  10.         @palabras = split (' ',@lineas[$i]);
  11.         print "@palabras\n";
  12.  
  13.         while ($s=0)
  14.         {
  15.                 if (@palabras[$i] == $storage)
  16.                 {
  17.                 print @palabras[$i];
  18.                         print "@palabras[$i]\n";
  19.                 }
  20.                 else
  21.                 {
  22.                         $s=1;
  23.                 }
  24.  
  25.         }
  26.         while ($s=1)
  27.         {
  28.                 if (@palabras[$i] != $fin)
  29.                 {
  30.                         $s=1;
  31.                 }
  32.                 else
  33.                 {
  34.                         $s=0;
  35.                 }
  36.         }
  37. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Muchas gracias de antemano,

Un saludo,
Alex
gandalfalexgan
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2010-07-08 03:48 @200

Publicidad

Re: Eliminar frases desde una palabra clave hasta otra,

Notapor gandalfalexgan » 2010-07-08 08:48 @408

Después de mucho googlear, y buscar, he conseguido alguna mejora en el script (o eso creo) He tenido que liar algunos conceptos para poder obtener lo que buscaba. No ha salido del todo bien pero algo es algo. Ahora el script es así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. my %hash;
  3. open my $FICHERO, q[<], 'prueba.sql';
  4. $s=0;
  5. $i=0;
  6. while (my $linea = <$FICHERO>) {       #Abrimos while para linea
  7.           chomp $linea;                #Eliminamos el último espacio
  8.         my @palabras = split " ", $linea; #Separamos en palabras
  9.  
  10.                 while ($s==0){       #Opción 1 del selector
  11.                         if ( $palabras[$i] ne "STORAGE(INITIAL" )
  12.                         {
  13.                                 print "$palabras[$i]\n";
  14.                                 print "estoy aqui $s\n";
  15.  
  16.                                 $i=$i+1;
  17.                                 print "$i\n";
  18.                         }
  19.                         else
  20.                         {
  21.                                 $s=1; #LLamamos la opcion 2
  22.                                 print "estoy en el else $s\n";
  23.  
  24.                                 $i=$i+1;
  25.                         }
  26.                 }
  27.                 while ($s==1){   #Opcion 2 del selector
  28.                         if ($palabras[$i] ne "1)" ){
  29.                                $s=1;
  30.                                 $i=$i+1;
  31.                         }
  32.                         else
  33.                         {
  34.                                 $i=$i+1;
  35.                                 $s=0; #Invocamos la opción 1
  36.                         }
  37.  
  38.                 }
  39.  
  40. }
  41. close $FICHERO;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Me da varios problemas: 1.- solo lee la primera frase, 2.- entra en un bucle infinito, y 3.- el contador nunca para.

Estoy abierto a cualquier sugerencia, muchísimas gracias de antemano.

Un saludo,
Álex
gandalfalexgan
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2010-07-08 03:48 @200

Re: Eliminar frases desde una palabra clave hasta otra,

Notapor explorer » 2010-07-08 14:01 @626

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

Esta es una solución:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. open my $VIEJO, q[<], 'kk.txt';     # abrimos fichero en lectura
  7. open my $NUEVO, q[>], 'ww.txt';     # abrimos fichero en escritura
  8.  
  9. while (my $linea = <$VIEJO>) {      # por cada línea
  10.  
  11.     # la saltamos si está dentro del rango que no nos interesa
  12.     next if $linea =~ /STORAGE\(INITIAL/ .. $linea =~ / 1\)/;
  13.  
  14.     # sí es una línea que nos interesa: la guardamos
  15.     print $NUEVO $linea;
  16. }
  17.  
  18. close   $VIEJO;                     # cerramos ficheros
  19. close   $NUEVO;
  20.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Supongamos una entrada como esta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
  1. explorer@dv9210:~/Documentos/Desarrollo> cat kk.txt
  2. REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_INSTALACION"
  3. REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGUO"
  4. REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" DATE,
  5. REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  6. REM STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1) TABLESPACE
  7. REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" DATE,
  8. REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  9. REM "ABA_DATA" NOLOGGING NOCOMPRESS ;
  10. REM STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS
  11. REM "ABA_DATA" NOLOGGING NOCOMPRESS ;
  12. REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_INSTALACION"
  13. FREELIST GROUPS 1) TABLESPACE
  14. REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGUO"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

La salida es esta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
  1. explorer@dv9210:~/Documentos/Desarrollo> cat ww.txt
  2. REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_INSTALACION"
  3. REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGUO"
  4. REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" DATE,
  5. REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  6. REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" DATE,
  7. REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
  8. REM "ABA_DATA" NOLOGGING NOCOMPRESS ;
  9. REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGUO"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Se aprecian las diferencias:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
  1. explorer@dv9210:~/Documentos/Desarrollo> diff -y kk.txt ww.txt
  2. REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_I   REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_I
  3. REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGU   REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGU
  4. REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" D   REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" D
  5. REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXT   REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXT
  6. REM STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1) TABL <
  7. REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" D   REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" D
  8. REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXT   REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXT
  9. REM "ABA_DATA" NOLOGGING NOCOMPRESS ;                           REM "ABA_DATA" NOLOGGING NOCOMPRESS ;
  10. REM STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS         <
  11. REM "ABA_DATA" NOLOGGING NOCOMPRESS ;                         <
  12. REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_I <
  13. FREELIST GROUPS 1) TABLESPACE                                 <
  14. REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGU   REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGU
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Espero que te sirva. Y que te sirva también para animarte en el aprendizaje de Perl (han sido menos de 20 líneas, ¿eh? 8) )
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Eliminar frases desde una palabra clave hasta otra,

Notapor gandalfalexgan » 2010-07-08 14:27 @644

Grandísima solución, solo que hay un pequeño fallo, y es un fallo que no entiendo por qué,

Si te fijas en esta línea:

next if $linea =~ /STORAGE\(INITIAL/ .. $linea =~ / 1\)/;

la cadena va desde "STORAGE(INITIAL" , como quería, hasta "1)" como yo quería, sin embargo no lo está aplicando.

El texto original de una de las líneas decía:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
REM STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1) TABLESPACE
REM "ABA_DATA" NOLOGGING NOCOMPRESS ;"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


sin embargo el resultado que obtengo es:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
REM "ABA_DATA" NOLOGGING NOCOMPRESS ;"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


y debería ser,
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
REM TABLESPACE
REM "ABA_DATA NOLOGGING NOCOMPRESS ;"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

o
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
REM TABLESPACE "ABA_DATA NOLOGGING NOCOMPRESS;"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Alguna idea de cómo solucionarlo, y ante todo gracias, por el esfuerzo, de verdad.

¡Uff!, espero poder librarme de pasarme toda la noche trabajando en esto... ¡je,je!
Última edición por explorer el 2010-07-08 14:36 @650, editado 1 vez en total
gandalfalexgan
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2010-07-08 03:48 @200

Re: Eliminar frases desde una palabra clave hasta otra

Notapor explorer » 2010-07-08 14:49 @659

¡Ah!, creí que te referías a quitar líneas enteras... pero veo que se refiere a una secuencia entre palabras.

Bueno, pues entonces, usaremos una expresión regular, con un patrón de búsqueda y sustitución:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. open my $VIEJO, q[<], 'kk.txt';     # abrimos fichero en lectura
  7.  
  8. my $fichero = join q[], <$VIEJO>;   # leemos todo el fichero
  9.  
  10. close   $VIEJO;                     # cerramo fichero
  11.  
  12.  
  13. $fichero =~ s/STORAGE\(INITIAL .*? 1\)\s*//gsm;     # Magia
  14.  
  15.  
  16. open my $NUEVO, q[>], 'ww.txt';     # abrimos fichero en escritura
  17.  
  18. print $NUEVO $fichero;              # escribimos el resultado
  19.  
  20. close   $NUEVO;                     # cerramos
  21.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Ahora, la salida (con el mismo fichero de entrada anterior, es)
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
  1. explorer@dv9210:~/Documentos/Desarrollo> ./kk.pl; diff -y kk.txt ww.txt
  2. REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_I   REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_I
  3. REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGU   REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGU
  4. REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" D   REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" D
  5. REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXT   REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXT
  6. REM STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS 1) TABL | REM TABLESPACE
  7. REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" D   REM VARCHAR2(4), "ESTADO_NUEVO" VARCHAR2(4), "FECHA_CAMBIO" D
  8. REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXT   REM "FECHA_DATOS" DATE) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXT
  9. REM "ABA_DATA" NOLOGGING NOCOMPRESS ;                           REM "ABA_DATA" NOLOGGING NOCOMPRESS ;
  10. REM STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS         | REM TABLESPACE
  11. REM "ABA_DATA" NOLOGGING NOCOMPRESS ;                         <
  12. REM CREATE TABLE "NUEVODW"."ABALON_CAMBIO_ESTADO_INST" ("ID_I <
  13. FREELIST GROUPS 1) TABLESPACE                                 <
  14. REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGU   REM NUMBER, "CODIGO_INSTALACION" VARCHAR2(40), "ESTADO_ANTIGU
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

A ver si ahora hemos acertado...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Eliminar frases desde una palabra clave hasta otra

Notapor gandalfalexgan » 2010-07-08 15:02 @668

¡¡¡Finalmente lo has conseguido!!!

He aplicado el "filtro" sobre los dos exports que tenía, y aparentemente está bien.

Me has librado de una buena, había un equipo esperando por esos exports, y estaba en fecha límite.

Muchas gracias :)

Gracias
gandalfalexgan
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2010-07-08 03:48 @200

Re: Eliminar frases desde una palabra clave hasta otra

Notapor explorer » 2010-07-08 15:11 @674

Ahora que recuerdo, y lo vi la semana pasada, es que Oracle sigue trayendo Perl como apoyo, tanto a nivel de administración de servicios, como sistema de programación, incluyendo la librería DBD::Oracle.

En una base de datos que tenemos por aquí, con una base de datos Oracle 11g instalada, hay un proceso perl funcionando todo el tiempo, que cada cierto número de segundos, lanza nuevos procesos...

Cosas de Oracle ;)

La lástima, es que esa versión de Perl que trae... es un "poco" antiguo... (bueno, mucho).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

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