Como mover recursivamente lotes de 20 arquivos para pastas numeradas da pasta de 1000 arquivos

Como mover recursivamente lotes de 20 arquivos para pastas numeradas da pasta de 1000 arquivos

Tenho uma pasta cheia de 1.000 (ou mais) arquivos. Quero ter um script que crie uma pasta numerada e mova os primeiros 20 arquivos (ordenados por nome) para essa pasta. Deverá então fazer isso para os demais arquivos, aumentando o número da pasta em 1, até que todos os arquivos estejam nas pastas.

Eu tentei o seguinte comando, mas ele não cria um diretório inteiro automaticamente e não aumenta o número da pasta automaticamente:

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

Como isso pode ser feito usando o bash?

Responder1

Este script leva dois argumentos (opcionais), o diretório a ser particionado e o tamanho da partição. Como você não disse se deseja apenas mover arquivos ou mover tudo, presumi que você se referia a arquivos, então usei o comando find.

Alguns comentários,

  • Se você não especificou o shell, algo assim seria feito mais facilmente em perl, ruby ​​ou python.
  • find com maxprofundidade 1 faz apenas o diretório
  • você pode mover os arquivos para qualquer lugar, basta alterar o nome da pasta
  • como find é usado, você pode adicionar -name, -mtime, -ctime, etc.

Copie algum.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

Aqui está um script para testar (eu não tinha 1.000 arquivos extras disponíveis),

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

Responder2

Apenas um forloop deve ser suficiente quando seu nome de arquivo termina com números correspondentes, mas o shell é zsh.

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

Se estiver em bash, então:

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

Postagem de aprendizagem:Como posso usar $variable em uma expansão de chaves de uma sequência?

informação relacionada