Jue Abr 24, 2008 4:29 am
|
 |
xiuron
Perlero Nuevo

|
Registrado: 24 Abr 2008
Mensajes: 3
|
|
| Pasar a una variable solamente parte de una cadena de texto |
|
|
Hola,
Soy nuevo en el foro (y en Perl ); soy Javi... ¡ Encantado !.
Quiero usar Perl para simplificar algunas tareas de administración, pero me quedo pillado en cosas que seguramente sean muy simples.
He hecho un código para que el resultado de un comando sea almacenado en una variable. Pero de esta variable solo quiero un "trocito", me explico, quiero por ejemplo saber el nivel de "idle" de mi servidor. Mi código es este:
| Perl: | # !/usr/bin/perl
### Declaracion de variables ###
my $cpu;
### Asignacion de valores ###
$cpu= `top -n 1 | grep Cpu`;
### Salida por pantalla ###
# AQUI ME PIERDO JEJE
print "\n"; |
Pues eso... con top -n 1 | grep Cpu paso solo la línea de CPU del comando TOP, pero aun así me da a la variable muchas más cosas que el " 99" por ejemplo que quiero...
¿Como puedo coger solo los "dígitos" que yo quiera de una cadena de texto?
Gracias por ayudarme  |
|
|
|

Jue Abr 24, 2008 5:21 am
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4082
Ubicación: Valladolid, España
|
|
|
|
|
Bienvenido a los foros de Perl en Español, xiuron.
Se te ha pasado un detalle. top es un programa fundamentalmente interactivo y que, además, utiliza caracteres de control para pintar en toda la pantalla.
Bueno, resulta que si aplicamos una expresión regular para extraer la información que quieres:
| bash: | explorer@joaquin:~/Documents/Desarrollo> perl -le '$top = qx(top -n 1|grep Cpu); ($idle) = $top =~ m/([0-9.]+)\%id,/; print "->$top<-:->$idle<-"' |
no sale nada.
Es debido a que top está sacando caracteres de control para colocar y colorear las cifras que mostraría en la terminal:
| Código: |
explorer@joaquin:~/Documents/Desarrollo> top -n 1 |grep Cpu |hexdump -C
00000000 43 70 75 28 73 29 3a 1b 28 42 1b 5b 6d 1b 5b 33 |Cpu(s):.(B.[m.[3|
00000010 39 3b 34 39 6d 1b 28 42 1b 5b 6d 20 20 37 2e 35 |9;49m.(B.[m 7.5|
00000020 25 1b 28 42 1b 5b 6d 1b 5b 33 39 3b 34 39 6d 75 |%.(B.[m.[39;49mu|
00000030 73 2c 1b 28 42 1b 5b 6d 1b 5b 33 39 3b 34 39 6d |s,.(B.[m.[39;49m|
00000040 1b 28 42 1b 5b 6d 20 20 30 2e 38 25 1b 28 42 1b |.(B.[m 0.8%.(B.|
00000050 5b 6d 1b 5b 33 39 3b 34 39 6d 73 79 2c 1b 28 42 |[m.[39;49msy,.(B|
00000060 1b 5b 6d 1b 5b 33 39 3b 34 39 6d 1b 28 42 1b 5b |.[m.[39;49m.(B.[|
00000070 6d 20 20 31 2e 30 25 1b 28 42 1b 5b 6d 1b 5b 33 |m 1.0%.(B.[m.[3|
00000080 39 3b 34 39 6d 6e 69 2c 1b 28 42 1b 5b 6d 1b 5b |9;49mni,.(B.[m.[|
00000090 33 39 3b 34 39 6d 1b 28 42 1b 5b 6d 20 38 39 2e |39;49m.(B.[m 89.|
000000a0 30 25 1b 28 42 1b 5b 6d 1b 5b 33 39 3b 34 39 6d |0%.(B.[m.[39;49m|
000000b0 69 64 2c 1b 28 42 1b 5b 6d 1b 5b 33 39 3b 34 39 |id,.(B.[m.[39;49|
000000c0 6d 1b 28 42 1b 5b 6d 20 20 31 2e 37 25 1b 28 42 |m.(B.[m 1.7%.(B|
000000d0 1b 5b 6d 1b 5b 33 39 3b 34 39 6d 77 61 2c 1b 28 |.[m.[39;49mwa,.(|
000000e0 42 1b 5b 6d 1b 5b 33 39 3b 34 39 6d 1b 28 42 1b |B.[m.[39;49m.(B.|
000000f0 5b 6d 20 20 30 2e 30 25 1b 28 42 1b 5b 6d 1b 5b |[m 0.0%.(B.[m.[|
00000100 33 39 3b 34 39 6d 68 69 2c 1b 28 42 1b 5b 6d 1b |39;49mhi,.(B.[m.|
00000110 5b 33 39 3b 34 39 6d 1b 28 42 1b 5b 6d 20 20 30 |[39;49m.(B.[m 0|
00000120 2e 30 25 1b 28 42 1b 5b 6d 1b 5b 33 39 3b 34 39 |.0%.(B.[m.[39;49|
00000130 6d 73 69 2c 1b 28 42 1b 5b 6d 1b 5b 33 39 3b 34 |msi,.(B.[m.[39;4|
00000140 39 6d 1b 28 42 1b 5b 6d 20 20 30 2e 30 25 1b 28 |9m.(B.[m 0.0%.(|
00000150 42 1b 5b 6d 1b 5b 33 39 3b 34 39 6d 73 74 1b 28 |B.[m.[39;49mst.(|
00000160 42 1b 5b 6d 1b 5b 33 39 3b 34 39 6d 1b 5b 4b 0a |B.[m.[39;49m.[K.|
00000170 |
La información que queremos está ahí, pero mezclada con caracteres de control de presentación en terminal.
La solución pasa primero por intentar quitar esos caracteres de control. En la página man del top nos da la pista: la opción -b sirve para encauzar la salida del comando a otros programas.
Bueno, pues se lo agregamos:
| bash: | explorer@joaquin:~/Documents/Desarrollo> perl -le '$top = qx(top -b -n 1|grep Cpu); ($idle) = $top =~ m/([0-9.]+)\%id,/simo; print "->$top<-:->$idle<-"' | y ya sale la cifra correcta.
El programa Perl que estamos ejecutando es este:
| Perl: | #!/usr/bin/perl
$top = qx(top -b -n 1|grep Cpu );
($idle) = $top =~ m/ ([0- 9. ]+ )\ %id,/;
print "->$top<-:->$idle<-\n" | La captura de la parte 'idle' se hace por medio de una expresión regular (m//), aplicada a la variable $top. Lo que hace es: queremos capturar (()) todo (+) lo que se parezca a un número ([0-9.]) que preceda a la cadena %id,. Esta captura, de hacerse, debe pasar a la primera variable del array que se encuentre a la izquierda de esta operación. Ese array es ($idle), por lo que guardará en esa variable lo capturado (o lo dejará indefinido).
Aprender expresiones regulares es uno de los 3 pilares de la programación en Perl. Parece farragoso, pero ya ves que soluciona problemas en muy poco sitio y rápidamente.
¡Adelante!
Actualización: Naturalmente, en Perl hay muchas formas de hacerlo. Así que otra forma más es la más inmediata de todas: como la información está en posiciones fijas, sabemos entonces cómo extraerlas:
| bash: | joaquin:/etc/joe > perl -le 'print substr(qx(top -b -n 1|grep Cpu), 35, 5)'
88.2% |
Eso sí... Perl es conocido también por su adaptación a los cambios del entorno. Si un día cambia de funcionar el comando, es muy posible que con la primera solución siga trabajando, ya que no estamos indicando posiciones exactas, sino coincidencia de patrones. |
|

Jue Abr 24, 2008 8:14 am
|
 |
xiuron
Perlero Nuevo

|
Registrado: 24 Abr 2008
Mensajes: 3
|
|
|
|
|
Gracias amigo,
Yo lo había solucionado mirando por diversas web de esta manera:
| Perl: | my cpu= `top -n 1 | grep Cpu`;
my $cpuc = substr $cpu, - 22, 4; |
Pero, leyendo lo que me cuentas, veo que ésta es una manera un tanto "cutre" de hacerlo; me interesa bastante más la primera manera que cuentas... ¡Voy a estudiarla!
Gracias... Javi  |
|
Jue Ago 07, 2008 12:18 pm
|
 |
Kiloko
Perlero Adicto

|
Registrado: 10 Jul 2007
Mensajes: 244
Ubicación: MOnterrey NL
|
|
|
|
|
Eso suena superbien. Es más o menos lo que estoy buscando pero con un Df -K... voy a ver si puedo adaptar lo que propones...
Saludos |
|
Powered by phpBB © 2001, 2005 phpBB Group
|