Eliminar todos los archivos excepto algunos de un directorio

Al usar sudo rm -r , ¿cómo puedo eliminar todos los archivos, con la excepción de lo siguiente:

 textfile.txt backup.tar.gz script.php database.sql info.txt 

 find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete 

Si no especifica -type f find también mostrará una lista de directorios, que puede que no desee.


O una solución más general usando la combinación muy útil find | xargs find | xargs :

 find [path] -type f -not -name 'EXPR' -print0 | xargs -0 rm -- 

por ejemplo, elimine todos los archivos que no sean de texto en el directorio actual:

 find . -type f -not -name '*txt' -print0 | xargs -0 rm -- 

La combinación print0 y -0 es necesaria si hay espacios en cualquiera de los nombres de archivo que deben eliminarse.

 rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt) 

El extglob (Extended Pattern Matching) debe estar habilitado en BASH (si no está habilitado):

 shopt -s extglob 

find . | grep -v "excluded files criteria" | xargs rm

Esto mostrará una lista de todos los archivos en el directorio actual, luego enumerará todos aquellos que no coincidan con sus criterios (tenga cuidado con los nombres de directorio que coincidan) y luego los eliminará.

Actualización : en función de su edición, si realmente desea eliminar todo del directorio actual, excepto los archivos que enumeró, se puede utilizar:

 mkdir /tmp_backup && mv textfile.txt backup.tar.gz script.php database.sql info.txt /tmp_backup/ && rm -r && mv /tmp_backup/* . && rmdir /tmp_backup 

/tmp_backup un directorio de respaldo /tmp_backup (tienes privilegios de administrador, ¿no?), /tmp_backup archivos que hayas listado a ese directorio, eliminará recursivamente todo en el directorio actual (sabes que estás en el directorio correcto, ¿verdad?) , vuelve al directorio actual desde /tmp_backup y finalmente, elimina /tmp_backup .

Elijo que el directorio de la copia de seguridad esté en la raíz, porque si está intentando eliminar todo de forma recursiva desde la raíz, su sistema tendrá grandes problemas.

Seguramente hay formas más elegantes de hacer esto, pero este es bastante sencillo.

Suponiendo que los archivos con esos nombres existen en varios lugares en el árbol de directorios y desea conservarlos a todos:

 find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete 

Puede usar la variable de entorno GLOBIGNORE en Bash.

Supongamos que quiere eliminar todos los archivos excepto php y sql, entonces puede hacer lo siguiente:

 export GLOBIGNORE=*.php:*.sql rm * export GLOBIGNORE= 

Establecer GLOBIGNORE de esta manera ignora php y sql de comodines utilizados como “ls *” o “rm *”. Por lo tanto, si utiliza “rm *” después de establecer la variable, se eliminarán únicamente los archivos txt y tar.gz.

Prefiero usar la lista de sub consulta:

 rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"` 

-v, –invert-match selecciona líneas que no coinciden

\| Separador

Como nadie lo mencionó:

  • copie los archivos que no quiere borrar en un lugar seguro
  • borra todos los archivos
  • mover los archivos copiados de vuelta a su lugar

Un poco tarde para el OP, pero con suerte útil para cualquiera que llegue aquí mucho más tarde por google …

Encontré la respuesta de @awi y comento -delete por @Jamie Bullock realmente útil. Una sencilla utilidad para que pueda hacer esto en diferentes directorios ignorando diferentes nombres / tipos de archivos cada vez con un mecanografía mínima:

rm_except (o lo que sea que quieras nombrar)

 #!/bin/bash ignore="" for fignore in "$@"; do ignore=${ignore}"-not -name ${fignore} " done find . -type f $ignore -delete 

por ejemplo, para eliminar todo, excepto los archivos de texto y foo.bar:

 rm_except *.txt foo.bar 

Similar a @mishunika, pero sin la cláusula if.

Puedes escribir un ciclo para este …%)

 for x in * do if [ "$x" != "exclude_criteria" ] then rm -f $x; fi done; 

Probando que funcionó con:

 rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public) 

pero los nombres con espacios son (como siempre) duros. Virtualbox\ VMs también con Virtualbox\ VMs lugar de las comillas. Virtualbox VMs siempre ese directorio ( Virtualbox VMs ).

Sólo:

 rm $(ls -I "*.txt" ) #Deletes file type except *.txt 

O:

 rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf 

Si está usando zsh lo recomiendo encarecidamente.

 rm -rf ^file/folder pattern to avoid 

Con extended_glob

 setopt extended_glob rm -- ^*.txt rm -- ^*.(sql|txt) 

Esto es similar al comentario de @siwei-shen, pero necesita la bandera -o para hacer múltiples patrones. La bandera -o significa ‘o’

find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm

Haz que los archivos sean inmutables. Ni siquiera root podrá eliminarlos.

 chattr +i textfile.txt backup.tar.gz script.php database.sql info.txt rm * 

Todos los demás archivos han sido eliminados.
Eventualmente puedes restablecerlos mutable.

 chattr -i * 

Como nadie ha mencionado esto, en un caso particular:

 OLD_FILES=`echo *` ... create new files ... rm -r $OLD_FILES 

(o solo rm $OLD_FILES )

o

 OLD_FILES=`ls *` ... create new files ... rm -r $OLD_FILES 

Es posible que necesite usar shopt -s nullglob si algunos archivos pueden estar allí o no:

 SET_OLD_NULLGLOB=`shopt -p nullglob` shopt -s nullglob FILES=`echo *.sh *.bash` $SET_OLD_NULLGLOB 

sin nullglob, echo *.sh *.bash puede darle “a.sh b.sh * .bash”.

(Habiendo dicho todo eso, yo prefiero esta respuesta , aunque no funciona en OSX)

Puedes hacer esto con dos secuencias de comandos. Primero defina una matriz con el nombre de los archivos que no desea excluir:

 files=( backup.tar.gz script.php database.sql info.txt ) 

Después de eso, recorra todos los archivos del directorio que desea excluir, verificando si el nombre del archivo está en la matriz que no desea excluir; si no es así, elimine el archivo.

 for file in *; do if [[ ! " ${files[@]} " ~= "$file" ]];then rm "$file" fi done 

En lugar de ir por un comando directo, mueva los archivos requeridos a un directorio temporal fuera del directorio actual. A continuación, elimine todos los archivos usando rm * o rm -r * .

A continuación, mueva los archivos necesarios al directorio actual.