Aquí está la solución simple que probablemente debería usar:
mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif
La .keep
extensión no tiene nada de especial , esto solo hace que el nombre de archivo no termine temporalmente .gif
.
Si no debe cambiar el nombre del archivo (y hay situaciones de secuencias de comandos donde esto es importante):
for X in *.gif; do
if [ "$X" != "filename.gif" ]; then
rm "$X"
fi
done
O puedes escribirlo más corto así:
for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done
Puede preferir usar find
en su lugar; es muy poderoso, podría considerarlo más legible, y maneja mejor los nombres de archivos extraños con caracteres como *
en ellos .
find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete
He utilizado el -not
operador para facilitar la lectura, pero si el cumplimiento de POSIX es importante, si no está utilizando GNU find, o si se trata de un script que tiene la intención de redistribuir a otros o ejecutar en una variedad de sistemas, debería use el !
operador en su lugar:
find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete
Una cosa útil find
es que puede modificar fácilmente el comando para que no se distinga entre mayúsculas y minúsculas, para que también encuentre y elimine archivos con extensiones como .GIF
:
find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete
Tenga en cuenta que he utilizado -iname
en lugar de -name
para el patrón de búsqueda *.gif
, pero he no utilizado para filename.gif
. Presumiblemente, usted sabe exactamente cómo se llama su archivo y -iname
coincidirá con mayúsculas alternativas no solo en la extensión , sino en cualquier parte del nombre del archivo.
Todas estas soluciones solo eliminan archivos que residen inmediatamente en el directorio actual . No eliminan archivos no contenidos en el directorio actual, y no eliminan archivos que residen en subdirectorios del directorio actual.
Si desea eliminar archivos en todas partes contenidos en el directorio actual (es decir, incluidos en subdirectorios, y en subdirectorios de esos subdirectorios, etc. - archivos contenidos en el directorio actual o cualquiera de sus descendientes), use find
sin maxdepth -1
:
find . -not -name 'filename.gif' -name '*.gif' -delete
¡Ten cuidado con esto!
También puede establecer otros valores con -maxdepth
. Por ejemplo, para eliminar archivos en el directorio actual y sus hijos y nietos pero no más profundo:
find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete
¡Solo asegúrate de nunca poner -delete
primero, antes de las otras expresiones! Verás que siempre pongo -delete
al final. Si lo pones al principio, se evaluaría primero, y todos los archivos debajo .
(incluidos los archivos que no terminan en .gif
y los archivos en los directorios sub-sub-sub-sub profundos ... .
) se eliminarán.
Para obtener más información , ver las páginas del manual para bash
y sh
y para los comandos utilizados en estos ejemplos: mv
, rm
, [
, y (especialmente) find
.
find
, que es muy versátil.find
es de hecho un buen hallazgo.find
maneja los nombres de archivos extraños con*
ellos mejor que el for-loop? El bucle for maneja los archivos con*
multa, porque ha usado comillas dobles.Si está utilizando
bash
(el shell predeterminado), laextglob
opción de shell le permite usar una sintaxis extendida de coincidencia de patrones. Para habilitarlo, use elshopt
comando incorporado:(Incluyo esa línea en mi
.bashrc
archivo).Entre otras cosas, otorga acceso al
!()
operador, que coincide con cualquier patrón que no se encuentre dentro de los elementos parentales. Para su propósito:Hay más información disponible en
man bash
"Coincidencia de patrones".fuente
extglob
debe habilitarse, pero no pasa nada malo si está deshabilitada (en ese caso, esto simplemente no funciona). Y parece estar habilitado de manera predeterminada, aunque no tengoshopt -s extglob
ninguno de mis archivos de configuración (o los globales). Si hay una explicación simple de por qué me funciona de manera inmediata, puede agregarla a esta respuesta; o puedo publicar una nueva pregunta.Abra una Terminal con Ctrl+ Alt+ Ty escriba:
La diferencia entre
-delete
y-exec rm -vf {} \;
es que con la segunda opción, podrá ver qué archivos se han eliminado, debido a la-v
bandera. Eso es algo que no se puede hacer con la-delete
opción. (-name -delete
Imprimirá los nombres de archivo, perorm
con-v
revela si cada archivo fue exitosamente eliminado.)fuente
Ahí está la
GLOBIGNORE
variable. Deman bash
:Entonces, una forma simple es establecer
GLOBGINORE
el nombre de archivo en cuestión:Entonces, en tu caso:
Por supuesto, dado que
GLOBIGNORE
contiene patrones, puede usarlo siempre que desee excluir un patrón:Una ventaja (?!)
GLOBIGNORE
Es que su configuración excluye automáticamente.
y..
de ser emparejado, y permitedotglob
:Entonces, una forma simple de eliminar todos los archivos y carpetas en un directorio:
El
*
coincidirá con nombres de archivo que comienzan con.
, yaGLOBIGNORE
habilitadadotglob
, pero no va a coincidir.
o..
, por lo que no afectará el directorio padre de esa manera.fuente