Eliminar todos menos 1000 archivos aleatorios en un directorio

13

Dejé que un script de generación de datos se ejecute demasiado tiempo ahora tengo más de 200,000 archivos que necesito reducir a alrededor de 1000. Desde la línea de comandos de Linux, ¿hay una manera fácil de eliminar todos menos 1000 de estos archivos, donde los archivos que se retendrían no dependería del nombre del archivo ni de ningún otro atributo?

Malcolm Regan
fuente
¿El proceso que creó los archivos tenía una característica que relacionaba cada archivo con el anterior? Si es así, que seleccionar al azar sería importante obtener una muestra representativa. Si el proceso genera archivos que son aleatorios por naturaleza, puede eliminar todo después de los primeros 1000.
Fixer1234

Respuestas:

15

Eliminar todos menos 1000 archivos aleatorios en un directorio

Código:

find /path/to/dir -type f -print0 | sort -zR | tail -zn +1001 | xargs -0 rm

Explicación:

  1. Lista todos los archivos /path/to/dircon find;
    • print0: use \0( carácter nulo ) como delimitador de línea; para que las rutas de archivo que contienen espacios / líneas nuevas no rompan el guión
  2. Mezcle la lista de archivos con sort;
    • -z: use \0(carácter nulo) como delimitador, en lugar de \n(una nueva línea)
    • -R: Orden aleatorio
  3. Elimine las primeras 1000 líneas de la lista aleatoria con tail;
    • -z: trata la lista como delimitada por cero (igual que con sort)
    • -n +1001: muestra líneas que comienzan desde 1001 (es decir, omite las primeras 1000 líneas)
  4. xargs -0 rm - eliminar los archivos restantes;
    • -0: delimitado por cero, de nuevo

Por qué es mejor que la solución de quixotic *:

  1. Funciona con nombres de archivo que contienen espacios / líneas nuevas.
  2. No intenta crear ningún directorio (que ya puede existir, por cierto)
  3. No mueve ningún archivo, ni siquiera toca los 1000 "archivos de la suerte" además de enumerarlos find.
  4. Evita perder un archivo en caso de que la salida de findno termine con \n(nueva línea) por alguna razón.

* - crédito para quijotesca para | sort -R | head -1000, me dio un punto de partida.

rld.
fuente
Al ejecutar CentOS 6, recibía errores sobre operandos no válidos. Afortunadamente, no me preocupan los espacios en las rutas de archivos, por lo que eliminar esos operandos funcionó para mífind . -type f | sort -R | tail -n +1001 | xargs rm
Brad
@brad ¿Podría proporcionar los mensajes de error y su versión de find? Intentaré mejorar mi respuesta, solo necesito algo de información para trabajar.
rld.
3
tail: invalid option -- 'z'la versión de tail que tengo es 8.4
brad
Agregaría --no-run-if-empty a xargs para evitar errores si no hay un archivo (después de ejecutarlo dos veces por ejemplo)
fraff
1

Utilice un directorio temporal, luego findtodos sus archivos, aleatorice la lista con sorty mueva los 1000 primeros de la lista al directorio temporal. Elimine el resto, luego mueva los archivos del directorio temporal.

$ mkdir ../tmp-dir
$ find . -type f | sort -R | head -1000 | xargs -I "I" mv I ../tmp-dir/
$ rm ./*
$ mv ../tmp-dir/* .

Si xargsse queja de longitud de la línea, utilizar un número más pequeño con heady repetir el comando, según sea necesario (es decir, cambio -1000a -500y ejecutarlo dos veces, o el cambio a -200y ejecutarlo 5 veces).

Tampoco podrá manejar nombres de archivos que incluyan espacios; Como muestra la respuesta de @ rld , puede usar findel -print0argumento de, los -zargumentos de sorty head, y -0con xargspara garantizar el manejo adecuado del nombre de archivo.

Finalmente, si tmp-dirya existe, debe sustituir un nombre de directorio que no existe.

quijotesco
fuente
Esto fallará si alguno de los nombres de archivo enumerados findincluye un espacio.
rld.
0

Para los usuarios de mac, el siguiente script debería hacer.

find . -type f -print0 | tr '\0' '\n' | sort -R | tail -n +10000 | tr '\n' '\0' | xargs -0 rm

trpermitirá que sort y tail trabajen en listas con en \nlugar de \0.

Luca Di Liello
fuente
-2

Lo más fácil podría ser rm -rf el directorio, luego volver a ejecutar el script de generación de datos y asegurarse de que no se ejecute durante demasiado tiempo.

Lars Poulsen
fuente
Eso no es lo que pidió el OP. Quizás hacerlo no sea factible.