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ó:
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.