Necesito recorrer un directorio de forma recursiva y eliminar todos los archivos con extensión .pdf
y .doc
. Estoy logrando recorrer un directorio de forma recursiva pero no estoy logrando filtrar los archivos con las extensiones de archivo mencionadas anteriormente.
Mi código hasta ahora
#/bin/sh
SEARCH_FOLDER="/tmp/*"
for f in $SEARCH_FOLDER
do
if [ -d "$f" ]
then
for ff in $f/*
do
echo "Processing $ff"
done
else
echo "Processing file $f"
fi
done
Necesito ayuda para completar el código, ya que no voy a ninguna parte.
rm
es parte del código de OP, pero en realidad no es relevante para la pregunta formulada. Creo que sería más seguro si las respuestas se formularan usando un comando inofensivo comoecho
.Respuestas:
find
está hecho para eso.fuente
-delete
opción de encontrar .find ... -print0 | xargs -0 ...
, no raw find | xargs para evitar problemas con los nombres de archivo que contienen nuevas líneas.xargs
sin opciones casi siempre es un mal consejo y esta no es una excepción. Usar en sufind … -exec
lugar.Como seguimiento a la respuesta de Mouviciel, también puede hacer esto como un bucle for, en lugar de usar xargs. A menudo encuentro engorrosos los xargs, especialmente si necesito hacer algo más complicado en cada iteración.
Como han comentado varias personas, esto fallará si hay espacios en los nombres de archivo. Puede solucionar este problema configurando temporalmente el IFS (separador de campo interno) en el carácter de nueva línea. Esto también falla si hay caracteres comodín
\[?*
en los nombres de archivo. Puede solucionarlo deshabilitando temporalmente la expansión de comodines (globbing).Si tiene nuevas líneas en sus nombres de archivo, entonces tampoco funcionará. Estás mejor con una solución basada en xargs:
(Los corchetes escapados se requieren aquí para que se
-print0
apliquen a ambasor
cláusulas).GNU y * BSD find también tienen una
-delete
acción, que se vería así:fuente
for f in $(find ...)
. Simplemente no uses este método.Sin
find
:/tmp/*
son archivos en dir y/tmp/**/*
son archivos en subcarpetas. Es posible que tenga que habilitar la opción globstar (shopt -s globstar
). Entonces, para la pregunta, el código debería verse así:Tenga en cuenta que esto requiere bash ≥4.0 (o zsh sin
shopt -s globstar
o ksh con enset -o globstar
lugar deshopt -s globstar
). Además, en bash <4.3, esto atraviesa enlaces simbólicos a directorios así como a directorios, lo que generalmente no es deseable.fuente
for f in /tmp/**
será suficiente. Incluye los archivos del directorio / tmp.for f in /tmp/*.{pdf,doc} tmp/**/*.{,pdf,doc} ; do
**
es una buena extensión pero no portátil para POSIXsh
. (Esta pregunta está etiquetada como bash, pero sería bueno señalar que, a diferencia de varias de las soluciones aquí, esto realmente es solo Bash. O, bueno, también funciona en varios otros shells extendidos).Si quieres hacer algo de forma recursiva, te sugiero que uses la recursividad (sí, puedes hacerlo usando pilas, etc., pero bueno).
Dicho esto,
find
probablemente sea una mejor opción como ya se ha sugerido.fuente
Aquí hay un ejemplo usando shell (
bash
):fuente
Esto no responde su pregunta directamente, pero puede resolver su problema con una sola línea:
Algunas versiones de find (GNU, BSD) tienen una
-delete
acción que puede usar en lugar de llamarrm
:fuente
Este método maneja bien los espacios.
Editar, arreglos fuera de uno
fuente
Para bash (desde la versión 4.0):
Eso es todo.
La extensión final ".ext" allí para seleccionar archivos (o directorios) con esa extensión.
La opción globstar activa el ** (búsqueda recursiva).
La opción nullglob elimina un * cuando no coincide con ningún archivo / directorio.
La opción dotglob incluye archivos que comienzan con un punto (archivos ocultos).
Tenga en cuenta que antes de bash 4.3,
**/
también atraviesa enlaces simbólicos a directorios que no es deseable.fuente
La siguiente función iteraría recursivamente a través de todos los directorios en el
\home\ubuntu
directorio (estructura de directorio completa en ubuntu) y aplicaría las comprobaciones necesarias enelse
bloque.fuente
Esta es la forma más simple que sé hacer esto:
rm **/@(*.doc|*.pdf)
**
hace que esto funcione recursivamente@(*.doc|*.pdf)
busca un archivo que termine en pdf O docFácil de probar de forma segura al reemplazar
rm
conls
fuente
No hay razón para canalizar la salida
find
a otra utilidad.find
tiene una-delete
bandera incorporada.fuente
Las otras respuestas proporcionadas no incluirán archivos o directorios que comiencen con a. lo siguiente funcionó para mí:
fuente
Solo haz
fuente
Lo siguiente recorrerá el directorio dado de forma recursiva y enumerará todos los contenidos:
for d in /home/ubuntu/*; do echo "listing contents of dir: $d"; ls -l $d/; done
fuente
ls -l /home/ubuntu/*/
, así que es bastante inútil.Si puede cambiar el shell utilizado para ejecutar el comando, puede usar ZSH para hacer el trabajo.
Esto recorrerá recursivamente todos los archivos / carpetas.
fuente