Licencia Creative Commons

Sebastian Yesid Tabares, Alejandro Cortazar y Diego Javier Mena Amado

En algunas ocasiones tendremos que trabajar fuerte y si no documentamos: tendremos que trabajar doble. Esta entrada de blog les permitirá extraer archivos de un árbol de ficheros y sus metadatos asocidados. Para mí caso de trabajo, se realizo una copia de datos de un Windows Server 2003 y de manera rápida, se encontraron los ficheros .pdf para migrarlos a una biblioteca virtual.

En varias ocasiones tenemos la necesidad de mover, copiar o borrar varios ficheros de un mismo tipo o extensión a la vez, pero estos no se alojan libremente en un solo directorio, si no que se encuentran repartidos dentro una jerarquía de subdirectorios. En este caso los típicos comandos para mover/copiar/borrar archivos no nos sirven, ni siquiera los útiles comodines nos resuelven el problema. ¿Como lo hacemos entonces?

Suponga que tiene una estructura de directorios como esta, obtenida por el siguiente comando:

 $tree tutorial/

directorio1

Y queremos mover todos los ficheros .pdf a un nuevo directorio que tendremos vacío, ¿Como lo hacemos? Bueno, en el caso de Linux (y UNIX) podemos hacerlo en una sola operación gracias al siempre útil y versátil find con el siguiente comando (ejecutado desde el directorio raíz):

 $find . -type f -name *.pdf -exec mv {} ./nuevoDirectorio \;

Este comando nos encontraría todos los archivos con la extensión .pdf dentro de todos los directorios y subdirectorios y los iría moviendo uno a uno al nuevoDirectorio. Es un comando rápido y efectivo. Genéricamente, el comando sería así:

 $find directorio_origen -type f -name *.EXT -exec mv {} ./directorio_destino \;

donde EXT sería la extensión del tipo de archivo que queremos mover. Se puede emplear esta variante para copiar los archivos en vez de moverlos:

 $find directorio_origen -type f -name *.EXT -exec cp {} ./directorio_destino \;

Y esta otra para eliminarlos (¡emplear con cuidado!):

 $find directorio_origen -type f -name *.EXT -exec rm -f {} \;

Ahora bien, supongamos que el cliente le dijo que eran 2600 archivos pdf pero él obviamente no llevaba un registro de ello; para contar los ficheros extraídos, usaremos el siguiente comando:

 $ls | wc -l

Para tener en cuenta también los archivos ocultos:

 $ls -A | wc -l

Básicamente le arrojará en terminal el numero de archivos que se alojaron en el nuevoDirectorio. Conclusión: el cliente debió estimar muy bien, pues el numero de archivos .pdf que tenia su servidor era 2361.

Ahora bien; si deseáramos conocer información de algún archivo .pdf sin tener que abrirlos podríamos emplear el siguiente comando:

$pdfinfo fichero-archivo.pdf

En terminal nos aparecerán los metadatos de este fichero; esto nos muestra información del autor, del título e incluso del programa que se usó para crear el fichero. Como vemos, una información bastante interesante.

directorio2

Como en mi caso tenemos demasiado ficheros, se opta por emplear el siguiente Scritp de bash para realizarle el mismo proceso a todos los ficheros del nuevoDirectorio,

#!/bin/bash

echo 'Author, Title, CreationDate' >> $2
for file in $1/*.pdf
do
    c0=$(echo "${file}" | rev | cut -d '/' -f 1 | rev)
    c1=$(pdfinfo "${file}" | grep -i 'Author' | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//')
    c2=$(pdfinfo "${file}" | grep -i 'Title' | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//')
    c3=$(pdfinfo "${file}" | grep -i 'CreationDate' | cut -f 2 -d ':' | sed -e 's/^[[:space:]]*//')

    echo "$c0, $c1 , $c2 , $c3" >> $2
done

podremos extraer información de todos los archivos alojados en el nuevoDirectorio como lo es:

  • Nombre del archivo
  • Titulo del documento en el metadato
  • Usuario que genero el archivo
  • Fecha de creacion del archivo

Para su ejecución se debe, copiar el script dentro de la carpeta que contiene todos los ficheros .pdf, abrir un terminal, ubicar la ruta de la carpeta a analizar y ejecutar:

$ ./pdf.sh . prueba.csv

La salida del script es un fichero .csv que aloja separado por comas los datos anteriormente mencionados. El enlace al script directamente desde github lo dejamos por aquí para posibles mejoras en un futuro.