
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 for
bucle 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?