No creo que te refieras a recursivo, ya que eso implicaría que el script se llama a sí mismo. Probablemente quieres buscar subdirectorios de forma iterativa.
Arreglos simples a tu script original
Intenta agregar */
a *.tmp
, de la siguiente manera:
for f in */*.tmp; do
ext=''
case $(file -b "$f") in
*Excel*) ext='.xlsx' ;;
*Word*) ext='.docx' ;;
*PowerPoint*) ext='.pptx' ;;
*PDF*) ext='.pdf' ;;
# etc...
*) continue ;;
esac
mv "${f}" "${f}${ext}"
done
Lo anterior funcionará solo para un nivel de subdirectorios (no mencionas en tu respuesta qué tan profundos son tus subdirectorios).
Si tienes múltiples niveles de subdirectorios, entonces deberías usar el siguiente script en su lugar (que utiliza **/*.tmp
en lugar de */*.tmp
):
for f in **/*.tmp; do
ext=''
case $(file -b "$f") in
*Excel*) ext='.xlsx' ;;
*Word*) ext='.docx' ;;
*PowerPoint*) ext='.pptx' ;;
*PDF*) ext='.pdf' ;;
# etc...
*) continue ;;
esac
mv "${f}" "${f}${ext}"
done
Esto funcionará bien en ksh
.
Sin embargo, si estás usando bash
(versión 4 y superior), entonces necesitarás agregar al principio del script shopt -s globstar
, de la siguiente manera:
shopt -s globstar
for f in **/*.tmp; do
ext=''
case $(file -b "$f") in
*Excel*) ext='.xlsx' ;;
*Word*) ext='.docx' ;;
*PowerPoint*) ext='.pptx' ;;
*PDF*) ext='.pdf' ;;
# etc...
*) continue ;;
esac
mv "${f}" "${f}${ext}"
done
Mira esta respuesta a ¿Globo recursivo? para conocer las diversas advertencias al usar globos en bash
.
Recursión real
Si realmente quieres una forma recursiva de hacer las cosas, podrías usar el siguiente script.
Pasa a través del contenido del directorio, como antes (en tu versión original), pero si encuentra un subdirectorio, se llama a sí mismo (es decir, recursividad) y comienza un nuevo script (algo así - ve la última línea), y así sucesivamente. Una vez que se hayan agotado el subdirectorio (o subdirectorios), el script llamado recursivamente finaliza y el script que llama continúa su camino feliz - y así sucesivamente.
Recibe un parámetro, la ruta a tu directorio que deseas buscar, por lo que ahora no tienes que ejecutar el script mientras estás en el directorio a buscar (puedes ejecutarlo desde cualquier lugar):
#!/bin/bash
search_dirs () {
shopt -s nullglob dotglob
for the_path in "$1"/*; do
if [ -d "$the_path" ]; then
search_dirs "$the_path"
else # Tu script original
ext=''
case $(file -b "$the_path") in
*Excel*) ext='.xlsx' ;;
*Word*) ext='.docx' ;;
*PowerPoint*) ext='.pptx' ;;
*PDF*) ext='.pdf' ;;
# etc...
*) continue ;;
esac
mv "${the_path}" "${the_path}${ext}"
printf '%s renombrado a %s.\n' "${the_path}" "${the_path}${ext}"
fi
done
}
Para ser más precisos, no es el script lo que es recursivo, es la función, search_dirs()
, la que es recursiva.
Referencia:
Usando find ... -exec
nohillside me ha ganado con una versión superior, pero aquí hay un par de comandos de una sola línea (desordenados).
Alternativamente, podrías usar find -exec
, que es un poco más exhaustivo al recorrer subdirectorios. Entonces, algo como:
find . -type f -exec bash -c '[[ $(file -b "'{}'") == *"PDF"* ]] ' \; -exec sh -c '
for src; do
mv "$src" "${src}.pdf"
done' sh {} +
para cada una de las breves descripciones de archivo (file -b
), es decir, Excel
, Word
, PowerPoint
, PDF
, y así sucesivamente.
O (esencialmente lo mismo):
find . -type f -exec bash -c '[[ $(file -b "'{}'") == *"PDF"* ]] ' \; -exec bash -c 'mv $0 ${0.pdf}' "{}" \;
Referencias: