Cópia em lote para vários diretórios

Cópia em lote para vários diretórios

Tenho cerca de 9.000 arquivos em um diretório e quero transferi-los para 90 arquivos em 100 diretórios por ordem de nome de arquivo, ignorando qualquer restante. EmCopiar vários arquivos do nome de arquivo X para o nome de arquivo Y?,Calebeescreveu em umComente:

Se o objetivo é apenas agrupá-los, existe uma maneira MUITO mais fácil! ls | xargs -iX -n20 cp X target_folder/executaria cp em arquivos em lotes de 20 até que todos estivessem prontos.

Então, com base no uso de xargs, como eu poderia mudar o target_folder para criar uma nova pasta e repetir o comando 100 vezes?

Responder1

Em bash, tente o seguinte código:

#!/bin/bash

c=0

for f; do
    if ! ((c % 100)); then
        folder=folder_$(printf "%03d\n" $c)
        mkdir -p $folder
    fi

    [[ -d "$f" ]] || mv "$f" "$folder"
    ((c++))
done

Execute o script assim:

./script.bash *

Responder2

Esse comando não parece próximo do que você está tentando fazer. xargspode ajudar, mas é complicado de usar, a menos que você saiba que os nomes dos arquivos não contêm espaços em branco ou caracteres de aspas. Aqui está um loop de shell que despacha arquivos para subdiretórios recém-criados, 90 por diretório.

set -- *
# Set args to "$1" "$2" ... "$90"
i=1 args=
while [ $i -le 90 ]; do
  slice="$slice \"\${$i}\""
  i=$((i+1))
done
# Move files 90 at a time
i=0
while [ $# -ge 90 ]; do
  mkdir part$i
  eval "mv $slice part$i"
  shift 90
done
# 0 to 89 files remain in the current directory

Responder3

parallelsuporta a execução de vários comandos \;e {#}é o número de sequência:

ls|parallel -n90 mkdir {#}\;mv {} {#}

Ou se os nomes dos arquivos não contiverem espaços, aspas ou barras invertidas:

i=1;while read l;do mkdir $i;mv $l $((i++));done< <(ls|xargs -n90)

informação relacionada