sábado, 30 de diciembre de 2017

BASH - Usando Functions, IF, CASE, FOR


Vamos a probar como hacer un Script poniendo a prueba condicionales y ciclos , estos contenidos dentro de Funciones.

Se irá comentando con # las instrucciones del codigo, para que se pueda copiar y pegar directamente


[usermacizo@centos ~]# vim tuscript.sh

#-- Inicio del codigo

#!/bin/bash
## Este es un carrier que porta mis saltos de linea cuando no puedo poner un \n normal, por ejemplo se ve en los read -p .

cr=$(echo $'\n.')
cr=${cr%.}

## En estas entradas (STDIN) consigo settear las variables nI = Numero Inicial, nF = Numero Final.
## y orden = En que direccion hará la cuenta de numeros.

read -p  "Ingrese un numero inicial$cr: " nI
read -p  "Ingrese un numero final$cr: " nF
read -p  "Desea contar hacia [A]tras o hacia [E]frente$cr: " orden
echo $cr
forma="Hacia Adelante"

## Funcion para ejecutar operacion.
# Aqui se valida usando la funcion define que tipo de incremental hará (hacia atras o hacia enfrente)
# tambien se settean unas variables como el tipo de incremental que irá en el ciclo (este cambia si en la funcion validar no tiene logica) , el operando que depende tambien de la funcion validar.

function contarnumeros{
incremental="++";
operando="<=";
define

if [[ $var -eq 1 ]] 
Tomar en cuenta que  aquí no hay un "return"  en la función, excepto los estandares (0=success,  no zero = fallo)  , entonces la variable $var ya trae un valor .

then
incremental="--";
fi
echo "======================================================================================="
echo "Se comenzara en el número [$nI] y se terminará en el [$nF] , haciendolo de forma ["$incremental"]$forma $cr"
echo "<==========>"

## Notar que para definir el ciclo, se complementa con las variables operando e incremental que son ajustados en las funciones define y validar

for (( cC=$nI;cC$operando$nF;cC$incremental))
do
echo "Imprimiendo número:" $cC
done
}

function  define {
## En esta función se verifica con un case que la primera letra defina el orden, es decir si recibe
# la palabra "Atras" o "Enfrente" y en base a eso settear la variable "var" que será usada posteriormente.
# Tambien se asigna la variable forma para darle "verbosidad" al echo que aparece al final de la funcion contarnumeros

var=0
if [ ! -z $orden ]
then
case $orden in
[aA]*)
var=1;
forma="Hacia Atras"
;;
[Ee]*)
var=0
forma="Hacia Adelante"
;;
*)
var=0;
esac
validar var
fi
}

function validar {
##Aqui lo que se realiza es verificar que tenga logica que el numero inicial (nI) y el orden , es decir
# Si el orden es inverso, tiene que ser mayor el numero inicial al final, y de no ser así resettear las
# variables en el orden correcto.
# Esto se evalua tomando en cuenta la variable var setteada en la funcion define (donde 0 es hacia enfrente y 1 es hacia atras)

if [[ $var -eq 0 ]]
then
if [[ $nI -gt $nF ]]
then
  nT=$nI
  nI=$nF
  nF=$nT
fi
else 
if [[ $nF -gt $nI ]]
then
  nT=$nI
  nI=$nF
  nF=$nT
fi
operando=">=";

fi
}

## Ejecutar todo el tamal que se declaró anteriormente (Desde la función contarnumeros se llaman las funcs define y validar

contarnumeros $orden $nI $nF

#-- Fin del codigo

[usermacizo@centos ~]# sh tuscript.sh

CLI - Extraer valores desde XML por su tag

Hacer un par de días se me presentó una situación, en la que debía descargar una cantidad de imagenes barbara que estaban posteadas en un XML en la web.

Lo que se me ocurria era hacerle un grep a las lineas que contenian el filename de la imagen, y luego concatenarle la URL completa y pasarle un wget.

El plan sonaba bien, excepto que  XML, es un oneliner, es decir que todos los elementos van en una misma linea.

Total que me he decidido bajar la herramienta XMLStartlet  que lo pueden sacar el repositorio EPEL si estas en CentOS7 (para los Ubunteros, lo pueden instalar con el apt-get)

yum -y install  epel-release

yum -y install  xmlstartlet

Para usarlo, les recomiendo primero identificar lo siguiente:
  1. Si están usando namespace (dice xmlns al inicio del archivo) porque de eso depende la sintaxis.
  2. La ruta donde vas a echar las cosas (lo que descargues).
  3. Los campos disponibles del XML , con el comando:
          xmlstarlet el -u tuarchivo.xml
Nota: Los argumentos siguientes significan el(elementos) y -u (filtra elementos unicos), para mas info mirarle el --help.

Bueno, al meollo del asunto, para resolverlo use la siguiente linea.

(Mi archivo usa namespace, por lo que debo definirlo antes de hacer la operacion.)

xmlstarlet sel -N s=http://s3.amazonaws.com/doc/2006-03-01/ -t -v "/s:TagPadre/s:TagContenido/s:Imagen" tuarchivo.xml


A partir del STDOUT que genere, se puede redireccionar a otro archivo, enviarlo a un less, o cualquier cosa que en su imaginación puedan llevar a cabo.



Nota: Los argumentos siguientes significan 
sel seleccionar data.
-N definir namespace.
-t extraer como texto
-v extraer el value del tag

Para hacer la prueba, haganlo con este XML (lo guardan como tuarchivo.xml

<?xml version="1.0" encoding="UTF-8"?>

<TagPadre xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>uploadtrailhn</Name><Prefix></Prefix><Marker></Marker><MaxImagens>1000</MaxImagens><IsTruncated>true</IsTruncated><TagContenido><Imagen>00001104.JPG</Imagen><LastModified>2017-11-29T16:11:30.000Z</LastModified><ETag>&quot;4a6fe12d0a9589a9b42f25f09668a65c-1&quot;</ETag><Size>527164</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00001405.JPG</Imagen><LastModified>2017-11-30T09:18:05.000Z</LastModified><ETag>&quot;78f0f7a8f5ccdce14e7d334a0a654abd-1&quot;</ETag><Size>443011</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00001606.JPG</Imagen><LastModified>2017-11-30T09:18:05.000Z</LastModified><ETag>&quot;a7440f915a49dbe70b559c5e8abbb575-1&quot;</ETag><Size>625259</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00002104.JPG</Imagen><LastModified>2017-11-29T09:32:44.000Z</LastModified><ETag>&quot;8ac74a872a1932bd5d0a4136e259cde5-1&quot;</ETag><Size>549429</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00002405.JPG</Imagen><LastModified>2017-11-30T09:18:05.000Z</LastModified><ETag>&quot;de89135a04c7a1a15e54becd47dd8cf1-1&quot;</ETag><Size>443238</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00002606.JPG</Imagen><LastModified>2017-11-30T09:18:05.000Z</LastModified><ETag>&quot;65759310cc5eeb5c1c22193b844dfebc-1&quot;</ETag><Size>533083</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00003104.JPG</Imagen><LastModified>2017-11-29T10:48:44.000Z</LastModified><ETag>&quot;68bc66fd3a2c258594907866bf0098d8-1&quot;</ETag><Size>491562</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00003405.JPG</Imagen><LastModified>2017-12-01T20:43:05.000Z</LastModified><ETag>&quot;f2035bd835933ccaad83cb3f2992fe86-1&quot;</ETag><Size>453667</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00003606.JPG</Imagen><LastModified>2017-12-01T19:53:05.000Z</LastModified><ETag>&quot;342e05d1cb902c598f15e4c521d8ff39-1&quot;</ETag><Size>570140</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00004104.JPG</Imagen><LastModified>2017-11-29T15:03:17.000Z</LastModified><ETag>&quot;fc8b60f5e3d2ae1d8352388f6e0985de-1&quot;</ETag><Size>562117</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00004405.JPG</Imagen><LastModified>2017-11-29T19:10:29.000Z</LastModified><ETag>&quot;ad9afc68961bf71efd73dadefda7aaa6-1&quot;</ETag><Size>434733</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00004606.JPG</Imagen><LastModified>2017-11-29T19:10:30.000Z</LastModified><ETag>&quot;e83b14462ce035d5fbea9cffd63acb73-1&quot;</ETag><Size>561650</Size><StorageClass>STANDARD</StorageClass></TagContenido><TagContenido><Imagen>00005104.JPG</Imagen><LastModified>2017-11-29T10:38:44.000Z</LastModified><ETag>&quot;ba709e758307d443b901d99d972c2287-1&quot;</ETag><Size>547773</Size><StorageClass>STANDARD</StorageClass></TagContenido></TagPadre>