2012-05-05 9 views
17

Me gustaría saber si rm puede eliminar todos los archivos dentro de un directorio (pero no las subcarpetas o archivos dentro de las subcarpetas)?Eliminar todos los archivos en un directorio (no toque ninguna carpeta ni nada dentro de ellos)

Sé que algunas personas utilizan:

rm -f /direcname/*.* 

pero esto asume el nombre del archivo tiene una extensión que no todos lo hacen (Quiero que todos los archivos - con o sin una extensión para ser eliminado).

+0

es encontrar la única respuesta? Me sorprende que rm no pueda manejar esto sin dar advertencias, ya que parece una operación tan simple – toop

+1

¿Qué pasa con 'find'? Entiendo que es un poco torpe, pero es mejor mantener 'rm' simple y' find' stunky que pedir que se agreguen todas las características a 'rm' (lo cual es tan torpe como' find') – Shep

Respuesta

2

Puede utilizar

find /direcname -maxdepth 1 -type f -exec rm -f {} \; 
+2

Esto -es - fue recursivo, lo que OP no quería. – Jens

+0

Claro, olvidé el argumento maxdepth. Fijo. – tonio

7
find /direcname -maxdepth 1 -type f -exec rm {} \; 

Explicación:

  • find búsqueda de archivos y directorios dentro /direcname
  • -maxdepth restringe a la búsqueda de archivos y directorios que son hijos directos de /direcname
  • -type f restringe la búsqueda a los archivos
  • -exec rm {} \; ejecuta el comando rm {} para cada archivo (después de sustituir la ruta del archivo en lugar del {}).
+0

forma sofisticada de hacer ot –

+1

también puede usar '-delete' en lugar de' -exec rm {} \; ' – Shep

+0

@Shep, sí, eso es mejor. Aunque noté que Troller lo usó, entonces les dejo eso y no cambiaré mi respuesta. – huon

2

Una solución de la envoltura (sin el hallazgo -maxdepth no estándar) sería

for file in .* *; do 
    test -f "$file" && rm "$file" 
done 
+0

¿qué significa el espacio entre los 2 asterix? – toop

+0

En algunas shells o con ciertas configuraciones de parámetros, '*' no engloba los nombres de archivo que comienzan con un punto, por lo tanto solicito explícitamente todo '.profile' etc. con'. * '. El siguiente '*' engloba todos los demás archivos. Si este último también engloba los archivos dot, esto termina con nombres duplicados, lo cual es inofensivo, ya que el 'test -f' saltará el archivo ya eliminado. – Jens

33

Aunque hallazgo le permite borrar archivos usando -exec rm {} \; puede utilizar

find /direcname -maxdepth 1 -type f -delete 

y es Más rápido. Usar -delete implica la opción -depth, que significa procesar el contenido del directorio antes del directorio.

+0

usando '-delete' en lugar de' -exec' mantiene varias instancias de rm en ejecución para eliminar los archivos encontrados ejecutando ** find ** – user1055604

+0

Tuviste la respuesta más útil en todo el interwebz: D cheers! ¡Me hizo el día! –

+1

Use 'find. -maxdepth 1 -type f -delete' si ya está en el directorio – babonk

1

Algunas shells, notablemente zsh y quizás la versión 4 de bash (pero no la versión 3), tienen una sintaxis para hacer eso.

Con zsh que sólo podría escribir

rm /dir/path/*(.) 

y si usted quiere eliminar cualquier archivo cuyo nombre comience con foo, de forma recursiva en subdirectorios, se podría hacer

rm /dir/path/**/foo*(.) 

la característica estrella doble es (con mi mejor terminación interactiva en mi humilde opinión) en mi opinión, suficiente para cambiar a zsh por capas interactivas. YMMV

El sufijo punto entre paréntesis indica que desea que solo los archivos (no los enlaces simbólicos o directorios) se expandan por el shell zsh.

1

Unix no es DOS. No hay un campo especial de "extensión" en el nombre de un archivo. Cualquier carácter después de un punto es solo parte del nombre y se llama sufijo. Puede haber más de un sufijo, por ejemplo .tar.gz. El carácter de glob de shell * coincide con el carácter .; es ajeno a los sufijos. Entonces, el MS-DOS *.* es solo * en Unix.

Casi. * no coincide con los archivos que comienzan con .. Los objetos nombrados con un punto inicial son, por convención, "ocultos". No aparecen en ls a menos que especifique -a.

(esto significa que el . y .. entradas de directorio para "auto" y "padre" se consideran ocultas.)

Para que coincida con las entradas ocultas También, el uso .*

El comando rm no elimina directorios (cuando no se opera recursivamente con -r). Pruebe rm <directory> y vea. Incluso si el directorio está vacío, se rechazará.

Por lo tanto, la manera de quitar todos (no oculta) archivos, tuberías, dispositivos, tomas de corriente y los enlaces simbólicos a partir de un directorio (pero deje los subdirectorios solo) es, de hecho:

rm /path/to/directory/* 

para eliminar también los escondidos que comienzan con .:

rm /path/to/directory/{*,.*} 

Esta sintaxis es la expansión de llaves. La expansión de la abrazadera no es coincidencia de patrones; es sólo un corto mano para generar múltiples argumentos, en este caso:

rm /path/to/directory/* /path/to/directory/.* 

esta expansión tiene lugar primero primero y luego globbing tiene lugar para generar los nombres de ser eliminados.

Tenga en cuenta que varias soluciones publicados aquí tiene varios problemas:

find /path/to/directory -type f -delete 

# -delete is not Unix standard; GNU find extension 
# without -maxdepth 1 this will recurse over all files 
# -maxdepth is also a GNU extension 
# -type f finds only files; so this neglects to delete symlinks, fifos, etc. 

El GNU encontrar soluciones tienen la ventaja de que funcionan incluso si el número de entradas de directorio se va a eliminar es enorme: demasiado grande para pasar de una llamada única al rm. Otra ventaja es que el -delete incorporado no tiene problemas para pasar nombres de rutas divertidas a un comando externo.

La solución portátil para el problema de demasiadas entradas de directorio es una lista de las entradas con ls y el tubo de xargs:

(cd /path/to/directory ; ls -a | xargs rm --) 

Los paréntesis significan "hacer estos comandos en un sub-proceso"; de esta manera, se olvida el efecto del cd, que es útil en la creación de scripts. ls -a incluye los archivos ocultos.

Ahora incluimos un -- después de rm que significa "esta es la última opción; todo lo demás es un argumento sin opción". Esto nos protege contra las entradas de directorio cuyos nombres son indistinguibles de las opciones. ¿Qué ocurre si un archivo se llama -rf y termina en el primer argumento? Entonces tiene rm -rf ... que explotará subdirectorios.

0

englobamiento del shell simple hará:

% tree 
. 
├── 1 
├── 2 
├── 3 
├── 4 
├── 5 
└── bar 
    ├── a 
    ├── b 
    ├── c 
    ├── d 
    └── e 

1 directory, 10 files 

% rm -f * 
rm: cannot remove ‘./bar’: Is a directory 

% tree . 
. 
└── bar 
    ├── a 
    ├── b 
    ├── c 
    ├── d 
    └── e 

1 directory, 5 files 

como en respuesta Jens', puede que tenga que añadir un segundo rm -f .* pero esto es sólo si espera que los archivos ocultos en su directorio principal. No es necesario verificar el tipo (test -f) ya que la opción rm -f no eliminará los directorios. Sin embargo, esto también eliminará archivos "especiales" como enlaces simbólicos y dispositivos de bloqueo.

3

me gustaría saber si rm puede eliminar todos los archivos dentro de un directorio (pero no las subcarpetas o archivos dentro de las subcarpetas)?

Eso es fácil:

$ rm folder/* 

Sin la -r, el comando rm no tocará sub-directorios o los archivos que contienen. Esto solo eliminará los archivos en folder y no en los subdirectorios o sus archivos.

Verá errores que le dice que carpeta/foo es un directorio puede no puede ser eliminado, pero que en realidad es bien con usted. Si desea eliminar estos mensajes, simplemente redirigir STDERR:

$ rm folder/* 2> /dev/null 

Por cierto, el estado de salida del comando rm no puede ser cero, por lo que no se puede comprobar rm de errores. Si eso es importante, que tendrá que bucle:

$ for file in * 
> do 
> [[ -f $file ]] && rm $file 
> [[ $? -ne 0 ]] && echo "Error in removing file '$file'" 
> done 

Esto debería funcionar en BASH incluso si los nombres de archivo tengan espacios en ellos.

0

La forma más sencilla de hacerlo es utilizar:

rm * 

Con el fin de eliminar directorios, debe especificar la opción -r

rm -r 

por lo que sus directorios y nada de lo contenido en ellos se no se eliminará mediante el uso de

rm * 

por la página de manual de rm, su propósito es eliminar archivos, ¿Por qué esto funciona

Cuestiones relacionadas