Scripts útiles para automatizar tareas comunes

Cualquier mejora, comentario o sugerencia es bienvenida: usa el formulario correspondiente.
Esta obra está bajo una licencia de Creative Commons.

Versiones:


Sumario


Introducción

Bash (Bourne-Again Shell) es un intérprete de comandos y su cometido es interpretar las órdenes que le demos para su proceso por el núcleo. Aunque existen otros intérpretes, bash es uno de los más populares y el que se usa por defecto en la mayoría de las distribuciones modernas. Para más información, visitad el manual de referencia (en inglés) de bash.


Redimensionar imágenes

Con la proliferación de las cámaras digitales de muchos megapixels, la gente tiende a mandar fotografías en tamaño poster. Para remediar esto nada mejor que poder redimensionar todas las imágenes localizadas en un directorio especificado:

Aspectos que hay que tener en cuenta:

#!/bin/bash
echo ""
echo "** Redimensionador de fotos v0.01 **"
if [ -z "$1" ]; then
   echo "No has indicado dónde están las fotos."
   echo "Uso: $0 path [resolution]"
   echo ""
   exit
else
   TEMP=`echo "$1" | cut -b1`
   if [ "$TEMP" != "\\" ]; then
      RUTA="$PWD/$1"
   else
      RUTA=$1
   fi
fi
counter=1
resolution=1152x864
if [ -z "$2" ]; then
   echo "INFO: Se utiliza la resolución por defecto: 1152x864"
else
   resolution=$2
fi
echo "Lugar: $RUTA | Resolución: $resolution"
if [ -d "$RUTA/resize_$resolution" ]; then 
   echo "WARNING: El directorio destino YA existe"
else
   mkdir $RUTA/resize_$resolution
fi
for i in `ls $RUTA/ | grep -i jpg`; do
   echo "Now working on $i - Resizing to $resolution"
   convert -resize $resolution $RUTA/$i "$RUTA/resize_$resolution/$i"
   counter=`expr $counter + 1`
done
exit

Manejar datos del banco

El hecho de tener varias cuentas bancarias dificulta saber el estado global de nuestra economía. Nada mejor que centralizar esa información en una sencilla hoja de cálculo con la previa manipulación de datos para su sencilla importación.

Aspectos que hay que tener en cuenta:

#!/bin/sh
temp="$HOME/borrar"
echo ""
echo "** Adaptador de datos bancarios v0.02 **"
if [ -z "$1" ]; then
   echo "No hay fichero que adaptar."
   echo "Uso: `basename $0` fichero_original"
   echo ""
   exit
fi
# Pasar de iso-8859-15 a utf8 en formato UNIX
# Se eliminan las líneas vacías y los múltiples espacios en blanco
echo -n "Dando formato correcto al fichero... "
cat $1 | iconv -f iso-8859-15 -t utf-8 | dos2unix | sed '/^$/d' | sed 's/ \+/ /g' | sed 's/ "/"/g' > $temp
echo "OK"

# Para las líneas que tengan 5 campos separados por ";",dibujo 2;3;5;4
echo -n "Poniendo los campos en el orden adecuado... "
awk -F ";" '{ if(NF == 5)print($2";"$3";"$5";"$4);}' $temp > export_`date +%d%m%Y`.csv
echo "OK"

# Se borran los ficheros temporales
echo -n "Borrando ficheros temporales... "
if [ -a "$temp" ]; then
   rm -f $temp
fi
echo "OK"

Gestiona paquetes RPM instalados

Los que hemos ido actualizando diferentes versiones del sistema operativo Fedora nos hemos encontrado que algunos paquetes de repositorios no oficiales han dado problemas de versiones y dependencias bastante molestos. Para evitar tener paquetes duplicados, versiones antiguas y demás, está este script.

Aspectos que hay que tener en cuenta:

#!/bin/bash
# Se establece un directorio por defecto
PATH_SCRIPT=$PWD

# Se obtiene la lista de paquetes
echo -n "Obteniendo lista de paquetes (ordenada)... "
rpm -qa | sort > ${PATH_SCRIPT}/paquetes.txt
echo "OK"

# Se manipula para obtener el nombre
echo -n "Nos quedamos con los nombres de paquetes... "
while read paquete; do
   if [ -f ${PATH_SCRIPT}/borrar ]; then
      rm -f ${PATH_SCRIPT}/borrar
   fi
   token=1
   # El nombre completo se puede dividir hasta en 5 tokens
   i=2
   while [[ ! -s ${PATH_SCRIPT}/borrar && $i -lt 6 ]]; do
      version=`echo $paquete | cut -d '-' -f$i`
      let j=i-1
      token=$token",$j" 
      let i+=1
   done
   echo $paquete | cut -d '-' -f$token >> ${PATH_SCRIPT}/nombres

done < ${PATH_SCRIPT}/paquetes.txt
echo "OK"

echo -n "Buscando paquetes duplicados... "
cat ${PATH_SCRIPT}/nombres | uniq -d > ${PATH_SCRIPT}/dupe
echo "OK"
echo -n "Borrando ficheros temporales... "
rm -f ${PATH_SCRIPT}/nombres
rm -f ${PATH_SCRIPT}/paquetes.txt
echo "OK"

exit

Escuchar la radio por internet

Creo que es bastante intuitivo, así que no me enrollo. Ojo con MPlayer y los codecs para formatos de MS Windows.

Parece que la Cadena Ser se ha currado una manera un tanto poco transparente para poder escucharla por internet. Afortunadamente, se generó un hilo de discusión en Barrapunto y a partir de lo comentado por el usuario elui he incluído un pequeño script que se lo calcula de manera automática.

#!/bin/sh
playlist_ser=""
function calcula_ser {
   fecha=`date +%Y%m%d%H%M`
   clave=`wget --referer="http://www.cadenaser.com/player_radio.html" "http://www.cadenaser.com/comunes/player/gettoken.php?update=$fecha&file=SER_LQ" -q -O - | awk -F\' '{print $2}'`
   url="http://mfile3.akamai.com/7841/wsx/prisaffs.download.akamai.com/7807/live/_!/radios/cadenaser.asx?auth="
   playlist_ser="$url$clave&aifp=v01"
}

echo
echo " 1 = Cadena SER"
echo " 2 = RNE Radio 1"
echo " 3 = RNE Radio 3"
echo " 4 = RNE Radio 5"
echo " 5 = RNE Radio Exterior de Espana"
echo " 6 = Radio Marca"
echo " 7 = COPE"
echo " 8 = Kiss FM"
echo
echo -n "Selecciona emisora: "
read choice

if [ $choice == 1 ] ; then
# Cadena SER
calcula_ser
mplayer -nocache -playlist $playlist_ser

elif [ $choice == 2 ] ; then
# RNE Radio 1
mplayer -nocache -playlist http://www.rtve.es/rne/audio/r1live.asx

elif [ $choice == 3 ] ; then
# RNE Radio 3
mplayer -nocache -playlist http://www.rtve.es/rne/audio/RNE3.asx

elif [ $choice == 4 ] ; then
# RNE Radio 5
mplayer -nocache -playlist http://www.rtve.es/rne/audio/RNE5.asx

elif [ $choice == 5 ] ; then
# RNE Radio Exterior de Espana
mplayer -nocache -playlist http://www.rtve.es/rne/audio/reelive.asx 

elif [ $choice == 6 ] ; then
# Radio Marca
mplayer -nocache mms://wmedia.recoletos.es/radiomarca

elif [ $choice == 7 ] ; then
# COPE
mplayer -nocache -playlist http://stream.flumotion.com/cope/copefm.asf.asx

elif [ $choice == 8 ] ; then
# Kiss FM
mplayer -nocache -playlist http://216.246.4.18/asxfiles-live/ny60winlive7001.asx

elif [ $choice == 0 ] ; then
exit 0
else echo "Esa cadena no existe"
fi

Gestión de conexiones PPP

La última versión de este script está disponible en el documento sobre PCMCIA Option Fusion UMTS/GPRS/WiFi en GNU/Linux.


Diff con esteroides

Compara dos ficheros comprimidos de manera recursiva. También investiga ficheros comprimidos dentro de los originales

Aspectos que hay que tener en cuenta:

#!/bin/bash
#################################################
# Advanced diff v0.12 - 24/10/2007
# It compares archives (zip, jar, tar.gz, tar.bz2) recursively
# so when a compressed file is found, it is uncompressed
# and files inside compared as well
# Diff output is: diff_[file1]_vs_[file2]_[timestamp].txt
#################################################
TEMP="$HOME/borrar"
BIN_FILES="$TEMP/bin_files"
num_loop=0
MAX_LOOPS=5
# Checks if file exists (-1 if not) and if its format is supported (0 if it does, -2 if not)
function check_file {
   if [ ! -f "$1" ]; then
      echo "Not able to found file "$1", please check."
      return -1
   else
      format=`file $1 | awk '{ print $2 }' | tr "[:upper:]" "[:lower:]"`
      if [ $format != "zip" ] && [ $format != "bzip2" ] && [ $format != "gzip" ]; then
         echo "No valid file format encountered (`basename $1`): $format"
         return -2
      fi
   fi
}
# Extracts content from compressed file ($1) to temporary location ($2)
function extract {
   if [ ! -d $2 ]; then
      mkdir -p $2
      # Added support for other compression types: bz2, tar.gz
      # No support for more than 1 tar package inside compressed file
      format=`file $1 | awk '{ print $2 }' | tr "[:upper:]" "[:lower:]"`
      case $format in
         "zip")
            unzip -q $1 -d $2
         ;;
         "bzip2")
            # Modified for non GNU tar compatibility            
            # tar -xjf $1 -C $2
            bzip2 -d -c $1 | (cd $2;tar xf - )
         ;;
         "gzip")
            # Modified for non GNU tar compatibility
            # tar -xzf $1 -C $2
            gzip -d -c $1 | (cd $2;tar xf - )
      esac
   fi
}
# Returns 1 if there are more files to compare, 0 otherwise
# ToDo: optimize
function loop {
   echo -n "Uncompressing content... "
   if [ $num_loop -lt 1 ]; then
      EXT_DIR1=`echo "$TEMP/$1" | sed s/\[\.\]/_/g`
      EXT_DIR2=`echo "$TEMP/$2" | sed s/\[\.\]/_/g`
   else
      EXT_DIR1=`echo "$1" | sed s/\[\.\]/_/g`
      EXT_DIR2=`echo "$2" | sed s/\[\.\]/_/g`
   fi
   extract $1 $EXT_DIR1
   extract $2 $EXT_DIR2
   echo "OK"
   FILE1=`basename "$1"`
   FILE2=`basename "$2"`
   OUTPUT=diff_"$FILE1"_vs_"$FILE2"_`date +%H%M%S_%d%m%y`.txt
   diff -br -U0 $EXT_DIR1 $EXT_DIR2 > $OUTPUT
   if [ ! -s $OUTPUT ]; then
      echo "No differences found"
      return 0
   else
      # Search diff's output for binary files that need to be analyzed
      grep -i binary $OUTPUT | awk '{ if(NF eq 6)print($3" "$5);}' > $BIN_FILES
      if [ -s $BIN_FILES ]; then
         echo "Found `wc -w $BIN_FILES | awk '{ print $1 }'` more binary files to compare"
         return 1
      else
         return 0
      fi
   fi
}
function remove_temp {
   echo -n "Removing temporal files... "
   rm -f $BIN_FILES
   if [ -d $TEMP ]; then
      rm -rf $TEMP
   fi
   echo "OK"
}
###############################
# Here start the main program #
###############################
if [ $# -lt 2 ]; then
   echo "Usage: `basename $0` file1 file2"
   exit -1
fi
check_file $1
if [ $? -eq 255 ]; then
   echo "Exiting"
   exit -1
fi
check_file $2
if [ $? -eq 255 ]; then
   echo "Exiting"
   exit -1
fi
if [ $1 == $2 ]; then
   echo "Files are the same, no need to diff them"
   exit 0
fi
# Here starts the original comparison
loop $1 $2
# Goes for more files (see supported formats) if founded inside given ones
if [ $? -gt 0 ]; then
   while read line; do
      # $num_loop controls depth level, not number of files encountered at one level
      let num_loop+=1
      if [ $num_loop -gt $MAX_LOOPS ]; then
         echo "[INFO] $MAX_LOOPS loops reached. Maybe you enter into an infinite loop, increase MAX_LOOPS variable otherwise. Exiting"
         exit -1
      fi
      TEMP1=`echo "$line" | cut -d " " -f1`
      TEMP2=`echo "$line" | cut -d " " -f2`
      #ToDo: formatting - field start counting (same number of tabs as number of loops) from last loop baseline, not from the end!
      echo "   `echo "$TEMP1" | awk -F/ '{ print $(NF-num)"/"$NF}' num=$num_loop` <=> `echo "$TEMP2" | awk -F/ '{ print $(NF-num)"/"$NF}' num=$num_loop`"
      check_file $TEMP1
      if [ $? -eq 0 ]; then
         loop $TEMP1 $TEMP2
      else
         # False positive (not able to process)
         let num_loop-=1
      fi 
   done < $BIN_FILES
fi

# Removing useless paths from output file if it's not empty
if [ -s $OUTPUT ]; then
   sed "s|$TEMP/||g" $OUTPUT > tmp
   mv tmp $OUTPUT
else
   rm -f $OUTPUT
fi
remove_temp
exit 0


Creative Commons License
Esta obra está bajo una licencia de Creative Commons.