Cómo mover recursivamente lotes de 20 archivos a carpetas numeradas desde una carpeta de 1000 archivos

Cómo mover recursivamente lotes de 20 archivos a carpetas numeradas desde una carpeta de 1000 archivos

Tengo una carpeta llena de 1000 (o más) archivos. Quiero tener un script que cree una carpeta numerada y luego mueva los primeros 20 archivos (ordenados por nombre) a esa carpeta. Luego debería hacer esto para los demás archivos, aumentando el número de carpeta en 1, hasta que todos los archivos estén en carpetas.

Probé el siguiente comando, pero no crea un directorio completo automáticamente y no incrementa el número de carpeta automáticamente:

N=1000;
for i in ${srcdir}/*; do
  [ $((N--)) = 0 ] && break
  cp -t "${dstdir}" -- "$i"
done

¿Cómo se puede hacer esto usando bash?

Respuesta1

Este script toma dos argumentos (opcionales), el directorio a particionar y el tamaño de la partición. Como no dijiste si solo querías mover archivos o mover todo, supuse que te referías a archivos, así que usé el comando buscar.

Algunos comentarios,

  • Si no hubiera especificado Shell, algo como esto se haría más fácilmente en Perl, Ruby o Python.
  • buscar con max Depth 1 solo hace el directorio
  • Puedes mover los archivos a cualquier lugar, simplemente cambia el nombre de la carpeta.
  • dado que se usa buscar, puede agregar -name, -mtime, -ctime, etc.

Copiar.sh,

#!/bin/bash
path=${1:-"."} #directory to start
howmany=${2:-20} #partition size
pushd $path; #move there
part=1; #starting partition
LIST="/usr/bin/find -maxdepth 1 -type f" #move only files?
#LIST="ls" #move everything #be careful, $folder will get moved also :-)
count=`$LIST |/usr/bin/wc -l`; #count of files to move
while [ $count -gt 0 ]; do
    folder="folder-$part";
    if [ ! -d $folder ]; then /usr/bin/mkdir -p $folder; fi
    /usr/bin/mv `$LIST |/usr/bin/sort |/usr/bin/head -$howmany` $folder/.
    count=`$LIST |/usr/bin/wc -l`; #are there more files?
    part=$(expr $part + 1)
done
popd $path

Aquí hay un script para probar (no tenía 1000 archivos adicionales por ahí),

for f in 0 1 2 3 4 5 6 7 8 9; do
  for g in 0 1 2 3 4 5 6 7 8 9; do
    for h in 0 1 2 3 4 5 6 7 8 9; do
        touch $f$g$h
    done
  done
done

Respuesta2

Solo un forbucle debería ser suficiente cuando el nombre de su archivo termine con los números correspondientes pero el shell sea zsh.

for N in {0..800..20}: do
    mkdir "dir$N"
    mv "files{$N..$((N+19))}" "/path/to/dir$N/"
done

Si está en bash, entonces:

for N in {0..800..20}: do
    mkdir "dir$N"
    eval mv "files{$N..$((N+19))}" "/path/to/dir$N/"
done

Publicación de aprendizaje:¿Cómo puedo usar $variable en una expansión de llave de shell de una secuencia?

información relacionada