Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

IF condition that doesnt work

by Sombrerero_loco (Beadle)
on Dec 23, 2009 at 11:00 UTC ( [id://814074]=perlquestion: print w/replies, xml ) Need Help??

Sombrerero_loco has asked for the wisdom of the Perl Monks concerning the following question:

Hi there. Im triying to do a script that open a files, read it, go throught some if conditions and do things using this if's. This script open a file and read inside a hash all the info, then, look for files, uncompress (hacked for testing), read the line from the file A, look throught the if conditions to substitute the values es $vl_read and then write it in another file, then recompres (hacked too) and delete the original files (hacked again). My problem its when i need to check the line using ReGex, i have the check if the lines named (hwUserField7) exists, and if dont, it must use the data store in hwUserField3 to look for in the has i had readed from the file, then must write the value referenced from this key in the hash as a new line. My problem its i dont able to put into the if contition of the flag to check if exists the line. I know your wisdom will clarify this, also, if you have a better code, i'll use :) Thanks Perl Masters

#!/usr/local/bin/perl use CGI qw(:all); use POSIX 'strftime'; use Data::Dumper; #Variable Global de tiempo para el fichero y para el log $timexml = lc strftime("%y-%m-%d %H:%M:%S", localtime); $time = lc strftime("%d-%m-%y %H:%M:%S", localtime); $uco = "ucos.txt"; my %uco; #Abrimos fichero de ucos y cargamos a hash open (UCO, "<$uco") or warn "$time - No se puede abrir el fichero de u +co, revisalo. Debe de llamarse ucos.txt\n"; while (<UCO>) { chomp; $rd0 = $_; ($vTrash1, $vTrash2, $vUco, $vNombre) = split /;/, $rd0, 4; $vNombre=&castellano($vNombre); $uco{$vUco}{'uco'} = $vUco; $uco{$vUco}{'nombre'} = $vNombre; print "cargando a fichero --> $vUco | $vNombre\n"; } close UCO; #Fichero de log $logfile = "log_file.log"; open (LOG, ">>$logfile") or warn "$time - no se ha podido abrir el fic +hero de log, continuamos sin log\n"; #Abrimos directorio y los metemos en un array para luego descomprimirl +os opendir (THISDIR, ".") or die "No se ha podido abrir el directorio: $! +, compruebalo\n"; @ar_listfiles = readdir (THISDIR); printf LOG "$time - Comenzamos tarea...\n"; print "$time - Comenzamos tarea...\n"; #Descomprimimos ficheros con 7z y guardamos referencia en array, para +luego borrarlos printf LOG "$time - Descomprimiendo Scanfiles....\n"; foreach $v1 (@ar_listfiles) { if ($v1 =~ /(\w+)\.xsf/){ my @run_extract = ("7z.exe e -y $v1"); system (@run_extract); push @ar_xsffile, $v1; } else{ next; } } #Borramos los ficheros, porque a veces se queda pillado y no se puede +borrar. foreach $del1 (@ar_xsffile){ unlink $del1; } #Cerramos y volvemos a abrir para que nos haga un listdir closedir (THISDIR); opendir (THISDIR, "."); #Volvemos a leer directorio para saber los xml que tenemos @ar_listfiles = ""; @ar_listfiles = readdir (THISDIR); print "$time - Modificando la fecha en los ScanFiles, espera que esto +tarda...\n"; #Abrimos el fichero, buscando el string vl_read y sustituimos por $tim +exml #y los escribimos a un nuevo fichero que luego debemos de re-comprimir printf LOG "$time - Modificando fecha a $time\n"; print "$time - Modificando fecha a $time\n"; foreach $tmp5 (@ar_listfiles){ if ($tmp5 =~/(\w+)\.xml/){ #Sistema de Flags para poder agregar la linea cuando sea ne +cesario $flag = 1; $flag2 = 0; $i = 0; ############################################################## +#### open (LEEXML, "$tmp5") or warn "$time - No se puede abrir el f +ichero xml $tmp5, hay algun problema.\n"; $xml_out = "$tmp5"."."."processed"; open (ESCRIBEXML, ">$xml_out") or warn "$time - No se puede es +cribir el nuevo xml\n"; RERUN:while ($vl_read = <LEEXML>){ if ($vl_read =~ /<hwScanDate type=\"attrib\">(.+?) +<\/hwScanDate>/ && $flag2 == 0 ){ $vl_read = "\t \<hwScanDate type=\"attrib\">2 +0$timexml<\/hwScanDate>\n"; printf LOG "$time - Se ha encontrado este stri +ng ->$1 y se sustituye por 20$timexml\n"; print "$time - Cambiamos fecha de $tmp5\n"; print "$time - Llega a MODIFICAR FECHA\n"; print "$time - Bloqueamos entrada cambiando el + flag2 a 1\n"; $flag2 = 1; } else { if ($vl_read =~ /<hwAssetUserField3 type=\"att +rib\">(.+?)<\/hwAssetUserField3>/){ $vNombre = $1; $vNombre = &castellano($vNombre); print "$time - Encuentra UCO $vNombre, hay + que compararla ahora\n"; } if ($vl_read =~ /<hwAssetUserField7 type="attr +ib">(.+?)<\/hwAssetUserField7>/){ $flag = 0; print "$time - Este fichero ya tiene codig +o de BAE, ignoramos\n"; } if ($flag == 1){ print "$time - pasa condicion de flag, vam +os a escanear\n"; foreach $vtem_uco (keys %uco){ print "ataca al valor ->$uco{$vtem_uco +}{'Nombre'}\n"; $i++; if ($uco{$vtem_uco}{'nombre'} eq $vNam +e ){ print "Buscando nombre $uco{$vtem_ +uco}{'Nombre'} y compararlo contra $vName\n"; $vl_read = "\t \<hwAssetUserField +7 type=\"attrib\">$vtem_uco<\/hwAssetUserField7>\n"; print "$time - Linea no encontrada +, le agregamos -> $vtem_uco\n"; $i = 20; } #else{ #$i++; #} } } } #print "$vl_read\n"; printf ESCRIBEXML "$vl_read"; } print "$time - Escribimos el fichero\n"; close LEEXML; close ESCRIBEXML; #hackeado para que no borre mientras estamos en pruebas #unlink $tmp5 or warn "no se puede borrar el fichero $tmp5\n"; $xml_done = $tmp5; rename $xml_out, $xml_done; push @ar_xmldone, $xml_done; } else{ next; } } #Hack para que no me comprima mientras estamos en pruebas goto ADIOS; #Ahora recomprimimos el fichero y lo dejamos como un xsf. Podemos usar + los valores #del array @vl_xsf o hacer uno nuevo printf LOG "$time - Recomprimiendo ScanFiles a xsf, espera....\n"; $c1 = 0; foreach $tmp6 (@ar_xmldone){ if ($tmp6 =~/(\w+)\.xml/ ) { $xsf_name = "$1"."."."xsf"; } my @run_compress =("7z.exe a -tgzip $xsf_name $tmp6"); $c1++; system (@run_compress); unlink $tmp6; } printf LOG "$time - Se han procesado $c1 ScanFiles en total\n"; #Ale, listo!!! printf LOG"$time - Tarea completada\n"; print "$time - Tarea completada!!\n"; #Cerramos todo y nos vamos pá casa que ya es tarde. ADIOS:close LOG; closedir THISDIR; sub castellano { + #Esto nos cambia las palabras acentuadas + #para no tener problemas de compatibilidad $vNombre = $_[0]; $vNombre=~ tr/á/a/; $vNombre=~ tr/é/e/; $vNombre=~ tr/í/i/; $vNombre=~ tr/ó/o/; $vNombre=~ tr/ú/u/; $vNombre=~ tr/ñ/n/; $vNombre=~ tr/Á/A/; $vNombre=~ tr/É/E/; $vNombre=~ tr/Í/I/; $vNombre=~ tr/Ó/O/; $vNombre=~ tr/Ú/U/; $vNombre=~ tr/Ñ/N/; $vNombre=~ tr/'/ /; $vNombre=~ tr/"/ /; $vNombre=~ tr/º/o/; $vNombre=~ tr/ª/a/; return $vNombre; } exit 0;

Replies are listed 'Best First'.
Re: IF condition that doesnt work
by suaveant (Parson) on Dec 23, 2009 at 13:16 UTC
    It is good to have the entire code listed, but could you point out exactly which part doesn't seem to be working?

    Not part of your problem but a good to know, tr can take an entire list of characters and transliterate them to a second list, so instead of doing one for each letter you can do something like:

    $vNombre=~ tr/áéí/aei/;
    Less typing and probably quite a bit more efficient.

                    - Ant
                    - Some of my best work - (1 2 3)

Re: IF condition that doesnt work
by vitoco (Hermit) on Dec 23, 2009 at 14:34 UTC
    My problem its when i need to check the line using ReGex, i have the check if the lines named (hwUserField7) exists, and if dont, it must use the data store in hwUserField3 to look for in the has i had readed from the file, then must write the value referenced from this key in the hash as a new line. My problem its i dont able to put into the if contition of the flag to check if exists the line.

    Please note that in your code, the conditions use "hwAssetUserField7" and "hwAssetUserField3".

    Also, you are reading that XML file line by line and testing each for the whole pattern "<tag>data</tag>". Is it possible that the opening tag to be in one line of the file and the closing tag to be in another? Then you should slurp the entire file and then perform the IFs.

    BTW, if both matching tags are always in the same line, you can use if (cond3) {...} elsif (cond7) {...}.

    Instead of uncompressing->processing->recompressing files, I would open files through a pipe, to get data uncompressed on the fly, and do the same to the output:

    open(LEEXML, "7z.exe e -so $tmp5|") or die; open(ESCRIBEXML, "|7z.exe a -si -tgzip $xml_out") or die;

    It will save space on disk, but I'm not sure if this performs.

      It will save space on disk, but I'm not sure if this performs.

      Slightly off-topic, but it generally will perform much better, at least once you get past the threshold of launching another process (perhaps using PerlIO::gzip would eliminate that). That's because, in general, the amount of CPU time it takes to decompress something is miniscule relative to the amount of time it takes to read the uncompressed information from disk. That is, reading compressed data plus the CPU overhead of decompressing that data is a fraction of the time required to read the data if it weren't compressed, because disks are so slow.

      Note that there are a few assumptions here: a) the amount of space saved by compression is significant (1% compression may not be a big deal, but 50%+ is), b) there are spare CPU cycles on the system, i.e., you're idling while waiting for the disk to catch up (a heavily used server that does a lot of CPU crunching may not qualify), c) traditional disks are used, i.e., disks with moving parts (SSD may, or may not, change this equation, though the cost of the storage space may be a different factor in favour of compression). Since all of these assumptions hold most of the time, I use the term "generally will" above instead of merely "can".

      Thanks for the tip, i'll implement that in my future codes, i don't know this can be possible. Also, for this piece of code is not necessary,because i only need to do that once a month as a scheduled task on a 8cpu SCSI RAID drives server (i dont care if this takes a lot of time, this server has this time to waste :) ) Also, i fix this problem using another aproximation: If i found condition 6, it write condition 6 and 7, and when i found condition 7, i trash it, because i wrote a cycle before. Smart, isnt? :) Thanks for all indeed, now i have another weird case with quotes. Im gonna open a new post.
Re: IF condition that doesnt work
by gmargo (Hermit) on Dec 23, 2009 at 14:13 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://814074]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (6)
As of 2024-04-24 23:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found