bash - una - eliminar archivos en unix
Eliminar todos los archivos excepto algunos de un directorio (17)
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)
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
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
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.
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 *
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
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
).
Puede hacer esto con el comando de líneas primero definir 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 recorrer todos los archivos del directorio que desea excluir, verificando si el nombre del archivo está en la matriz que no desea excluir, si no está, elimine el archivo.
$ for file in $(ls); do if [[ ! " ${files[@]} " ~= "$file" ]];then rm "$file";fi;done
¡Eso es todo!
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.
Puedes escribir un ciclo para este ...%)
for x in *
do
if [ "$x" != "exclude_criteria" ]
then
rm -f $x;
fi
done;
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)
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
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.
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.
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