2012-01-31 13 views

Respuesta

6

El siguiente debería funcionar:

dest_base="destination" 
src_dir="src/" 

filesperdir=500 
atfile=0 
atdir=0 
for file in $src_dir/*; do 
    if ((atfile == 0)); then 
     dest_dir=$(printf "$dest_base/%0.5d" $atdir) 
     [[ -d $dest_dir ]] || mkdir -p $dest_dir 
    fi 
    mv $file $dest_dir 
    ((atfile++)) 
    if ((atfile >= filesperdir)); then 
     atfile=0 
     ((atdir++)) 
    fi 
done 
+0

Eso funcionó perfectamente. ¡Gracias! – cesmarch

+0

Esto tiene la virtud de funcionar realmente, aunque si '$ src_dir/*' es demasiado largo o si dest_base se configuró para tener un espacio en él o si algún archivo tiene un espacio u otros caracteres especiales en el nombre, todavía habría una problema. – Sorpigal

+0

Nota: Este es un script bash (no un script sh) – Tom

-1

Se podría empezar con esto:

mkdir new_dir ; find source_dir | head -n 500 | xargs -I {} mv {} new_dir 

Esto creará new_dir 500 y mover archivos desde old_dir a new_dir. Todavía tiene que invocar esto manualmente para diferentes valores de new_dir hasta que el directorio anterior esté vacío, y debe tratar con nombres de archivo que contienen caracteres especiales.

0

, los siguientes archivos de la temperatura de la solución almacena OK con 500 listas de nombres de archivo. Adáptelo como lo necesite. En primer lugar, la lista de todos los archivos de directorio actual, divide 500 por 500, y almacenar los resultados en outputXYZ. * Archivos

ls | split -l 500 - outputXYZ. 
# Then we go through all those files 
count=0 
for i in outputXYZ.*; do 
    ((count++)) 
    # We store the result in dir.X directory (created in current directory) 
    mkdir dir.$count 2>/dev/null 

    # And move those files into it 
    cat $i | xargs mv -t dir.$count 

    # remove the temp file 
    rm $i 
done 

Al final, usted tiene todas sus imágenes en directorios dir.1 (1. .500), dir.2 (501..1000), dir.3, etc.

+1

Buggy! Mal uso de 'ls', sin comillas' rm $ i' (!), Etc. – Sorpigal

+0

Hola, no recibo su comentario "Bad us of ls". – huelbois

+2

La salida de 'ls' no es confiable para ningún otro propósito que no sea el consumo humano. Si necesita una lista de archivos en un formato confiable, debe usar 'find'. El análisis de la salida 'ls' se dividirá en una gran cantidad de casos de esquina. – Sorpigal

9

Un "simple" encontrar/xargs harían:

find -maxdepth 1 -type f -print0 | xargs -r -0 -P0 -n 500 sh -c 'mkdir newdir.$$; mv "[email protected]" newdir.$$/' xx 

Explicación:

  • encuentran
    • -maxdepth 1 impide encontrar desde la exploración recursiva los directorios, la seguridad, no se necesitan si sabe no tiene directorios
    • -type f solo encuentra los archivos
    • -print0 archivos separados con carbón nulo en lugar de LF (para manejar nombres extraños)
  • xargs
    • -r no se ejecutan con la lista de argumentos vacía
    • -0 archivos separados nula leer
    • -P0 cree tantos procesos como necesite
    • -n 500 ejecute cada proceso con 500 argumentos
  • sh
    • -c script de línea de comando de marcha proporciona como argumento siguiente
    • mkdir newdir.$$ hacer un nuevo directorio que termina con el proceso de shell PID
    • mv "[email protected]" newdir.$$/ mueven los argumentos de la secuencia de comandos (cada uno de ellos citado) a el directorio recién creado nombre
    • xx para la secuencia de comandos proporcionada línea de comandos (Ver manual de sh)

Tenga en cuenta que esto es no algo que usaría en la producción, se basa principalmente en el en el hecho de que $$ (PID) será diferente para cada proceso ejecutado por xargs

Si necesita los archivos ordenado puede trow un sort -z entre encontrar un xargs.

Si desea que los nombres de directorio más significativas se puede usar algo como esto:

echo 1 >../seq 
find -maxdepth 1 -type f -print0 |sort -z | xargs -r -0 -P1 -n 500 sh -c 'read NR <../seq; mkdir newdir.$NR; mv "[email protected]" newdir.$NR/; expr $NR + 1 >../seq' xx 
  • echo 1 > ../seq escribir el primer sufijo de directorio en un archivo (asegúrese de que no está en el directorio actual)
  • -P1 decirle a xargs que ejecute un comando a la vez para evitar condiciones de carrera
  • read NR <../seq lea el sufijo del directorio actual del archivo
  • expr $NR + 1 >../seq escribir el siguiente sufijo de directorio para la siguiente ejecución
  • sort -z ordenar los archivos
+0

+1, este es definitivamente el enfoque que usaría. – Sorpigal

Cuestiones relacionadas