rm -rf todos los archivos y todos los archivos ocultos sin. & .. error

83

rm -rf /some/path/* elimina todos los archivos no ocultos en ese directorio (y subdirecciones).

rm -rf /some/path/.* elimina todos los archivos ocultos en ese directorio (pero no subdirecciona) y también da el siguiente error / advertencia:

rm: cannot remove directory: `/some/dir/.'
rm: cannot remove directory: `/some/dir/..'

¿Cuál es la forma correcta de eliminar todos los archivos y carpetas ocultos y no ocultos de forma recursiva en un directorio de destino sin recibir la advertencia / error sobre .y ..?

Jake Wilson
fuente

Respuestas:

40

Siempre puedes enviar mensajes de error a /dev/null

rm -rf /some/path/.* 2> /dev/null

También podrías simplemente

rm -rf /some/path/
mkdir /some/path/

... entonces no tendrás que molestarte con los archivos ocultos en primer lugar.

maldad
fuente
2
Pero, ¿qué pasa si solo quiero eliminar los archivos ocultos?
CMCDragonkai 01 de
@CMCDragonkai esa debería ser una pregunta diferente, pero puede encontrar la solución en la respuesta de Gilles ( rm ..?* .[!.]*debería hacerlo).
evilsoup 01 de
15
No eliminar y volver a crear el directorio plantea el riesgo de que los permisos de archivo no sean correctos después (especialmente importante en entornos de servidor). ¿Quién podría crear la carpeta con los mismos permisos que antes automáticamente?
Yo Ludke
1
@YoLudke Tiene toda la razón, en muchas situaciones no importa, pero eliminar la carpeta y volver a crearla no es semánticamente equivalente a vaciar esa carpeta; ¡así que ten cuidado de hacer eso!
Thomas
Eliminar el directorio no siempre es posible. En mi caso, el directorio es un volumen acoplable, y aunque puedo hacer lo que quiera dentro del volumen, no puedo cambiar el volumen en sí mismo desde el contenedor.
dovidweisz
84

*coincide con todos los archivos que no son de punto, .[!.]*coincide con todos los archivos de punto excepto .y los archivos cuyo nombre comienza con .., y ..?*coincide con todos los archivos de punto-punto excepto ... Juntos coinciden con todos los archivos que no sean .y ... Si alguno de estos tres patrones no coincide con nada, se expande a sí mismo; rm -fno le importan los argumentos inexistentes, por lo que esto no importa.

rm -rf ..?* .[!.]* *

También puedes usar find. Esto es más complejo, pero tiene la ventaja de funcionar incluso si hay tantos archivos que los comodines anteriores se expandirían más allá del límite de longitud de la línea de comandos de su sistema.

find . -name . -o -prune -exec rm -rf -- {} +

Puede que le resulte más claro eliminar y volver a crear el directorio. Esto tiene la ventaja (o desventaja, según sea el caso) de dar como resultado un directorio vacío, incluso si otro programa está creando archivos al mismo tiempo en el directorio original.

Gilles
fuente
8
Esta debería ser la respuesta aceptada, ya que evita el cruce de padres y la posible eliminación.
rbellamy
La findalternativa devuelve "éxito" incluso si algún archivo no se elimina con éxito; No es bueno para el guión.
Franklin Yu
Con respecto a su segundo findcomando, la página de manual para encontrar estados "Debido a que -delete implica -depth, no puede usar -prune y -delete juntos". - ¿Aún lo usas -prune -delete?
Doktor J
@DoktorJ De hecho, -pruneno hace nada aquí. Y al volver a leer veo que no respondí la pregunta correctamente: me ocupé de no recurrir, pero la pregunta explícitamente solicita la eliminación recursiva. He corregido mi respuesta.
Gilles
2
@haylem En zsh, debe escribir en .[^.]*lugar de .[!.]*cuando la sustitución del historial está habilitada (que de forma predeterminada es el caso de forma interactiva pero no en scripts), porque zsh analiza !como referencia de historial. Pero en zsh no necesitaría eso en primer lugar, solo puede usar *(D)para incluir archivos de puntos (sin .o ..) en la coincidencia de comodines.
Gilles
21

Me acabo de dar cuenta de que esta es la forma más conveniente en la mayoría de las distribuciones de Linux:

ls -A1 | xargs rm -rf

dónde

-A= enumerar todo excepto . y..

-1 = poner cada artículo en una línea

Godzillante
fuente
44
La desventaja que veo es: necesita 'cd' en el directorio para hacer esto.
kumar
ls -A1 /your/path/ | xargs rm -rfdebería aplicar
godzillante
no .. no ayuda - Por ejemplo: ls -A1 ~ / test / | xargs rm -rf este comando elimina archivos en los que actualmente estoy 'cd' ... no en el directorio ~ / test.
kumar
55
No funciona si alguno de los nombres de archivo contiene espacios en blanco, líneas nuevas, comillas o barras invertidas.
Stéphane Chazelas
1
-1 Debido al comentario anterior. ↑↑↑↑↑↑↑↑
algo
15

Cambie la dotglobopción de su shell y use *, o use algo como find.

find somedir -mindepth 1 -delete
Ignacio Vazquez-Abrams
fuente
2
O simplemente podría rm -rf /some/diry luego crear un nuevo directorio vacío en su lugar.
tripleee
La mejor opción hasta ahora. Muy seguro ya que especifica explícitamente la ruta del directorio.
Yanick Girouard
4

Esto debería funcionar igual que @Gilles answer pero más compacto:

rm -rf {,.[!.],..?}*

o

rm -rf dir/to/files/{,.[!.],..?}*

También debe agregar un ifpara uso en scripts solo para estar seguro:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi
Paweł Prażak
fuente
1
Por extraño que parezca, como un alias bash en Ubuntu 16.04 LTS, la respuesta anterior no estaba funcionando. Sin embargo, lo alias cleandir='rm -rf {,.[!.],..?}*'hace.
Steven Ventimiglia
3

Encuentra es tu amigo.

find ! -name '.' ! -name '..' -delete

% find ! -name '.' ! -name '..'
./test
./test4
./test4/.test6
./test3
./.test5
./test2
% find ! -name '.' ! -name '..' -delete    
% find ! -name '.' ! -name '..'     
%             

Si desea utilizar la búsqueda recursiva en otro directorio actual ($ PWD), agregue una ruta justo después del findcomando; por ejemplo, find /path ! -name '.' ! -name '..' -delete. Si solo desea descender el nnúmero de directorios, use la -maxdepth nopción justo después del /pathparámetro.

El comando anterior se probó en un sistema Ubuntu 13.04. Es probable que funcione en otros sistemas Linux modernos.

sombreador
fuente
eliminar todos los directorios en el directorio actual que podrías hacerfind . ! -name '.' ! -name '..' -type d -delete
Andy
2

¿Cuál es la forma correcta de eliminar todos los archivos y carpetas ocultos y no ocultos de forma recursiva en un directorio de destino sin recibir la advertencia / error sobre. y ..?

Suponiendo que el directorio en cuestión es ./dir, entonces

rm -rf ./dir

eliminaría todos los archivos ./dir, incluidos los archivos y directorios ocultos, de forma recursiva e incluyendo el ./dirdirectorio en sí.

Si no desea eliminar el directorio en sí, puede volver a crearlo más tarde o usar

find ./dir -mindepth 1 -delete

o si findno es compatible -delete,

find ./dir -mindepth 1 -depth -exec rm -rf {} ';'

El uso le -mindepth 1permite mantener el directorio de nivel superior ./dir.

Kusalananda
fuente
esto debería ser marcado como la mejor respuesta
kitingChris
1

Te sugiero que experimentes con

Turn- SOBRE puntos (archivos ocultos)

  • conjunto dotglob

    shopt -s dotglob

Turn- OFF puntos

  • desarmado dotglob

    shopt -u dotglob

Este método funcionó exactamente como deseaba un comando de copia al que le faltaban los directorios ocultos.

    shopt -s    dotglob
    cp    -rvn  ./$from/*  ./$too/
    shopt -u    dotglob

Así que hice una eliminación (eliminar), y vaya ...

    shopt -s    dotglob
    rm -fr ../message_splitter--044a/*
    shopt -u    dotglob

... eso también funciona!

Se me ocurre que su querido lector no puede ver el message_splitterdirectorio. De cualquier manera, tiene una .svncarpeta que debe eliminarse y copiarse.

De la manpágina ...

dotglob Si se establece, bash incluye nombres de archivo que comienzan con un '.' en los resultados de la expansión del nombre de ruta.

referencias:

será
fuente
-2

Prueba este código:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
siz
fuente