Copie a estrutura de diretórios com número aleatório de arquivos

Copie a estrutura de diretórios com número aleatório de arquivos

Existe uma maneira elegante e rápida de copiar uma determinada estrutura de diretórios e selecionar apenas uma quantidade aleatória de arquivos a serem copiados com ela. Então, por exemplo, você tem a estrutura:

--MainDir
  --SubDir1
    --SubSubDir1
      --file1
      --file2
      --...
      --fileN
    --...
    --SubSubDirN
      --file1
      --file2
      --...
      --fileN
  --...

Quero copiar toda a estrutura de pastas, mas escolher apenas um número específico de arquivos aleatórios de {files1-filesN} de cada SubSubDir para serem copiados.

Responder1

Já que você marcou isso, linuxassumirei os utilitários GNU.

Copie a estrutura do diretório de $srcpara $dest:

find "$src" -type d -print0 | cpio -padmv0 "$dest"

Copie também uma amostra aleatória de $nfilearquivos de cada subdiretório folha de $src:

find "$src" -type d -links 2 -exec \
    sh -c 'find "$1" -type f -print0 | shuf -z -n "$2"' sh {} "$nfiles" \; | \
    cpio -padmv0  "$dest"

Aqui o primeiro findencontra subdiretórios folha ( -links 2), depois o segundo findencontra arquivos em cada um desses subdiretórios. shufescolhe uma amostra aleatória de arquivos e finalmente cpioos copia.

Responder2

Primeiro encontre todos os diretórios:

find MainDir -type d

Em seguida, analise esses diretórios em um script

find MainDir -type d -exec ./randomCopy.sh 2 {} \;

, qual

  1. Cria o diretório de destino
  2. Copiar é uma quantidade aleatória de arquivos.

Neste caso, 2 arquivos aleatórios são copiados.

No meu exemplo o script randomCopy.shfica assim:

#!/bin/bash                                                                                                                                                                                                                                                                    
cnt="$1"                                                                                                                                                                                                                                                                     
dir="$2"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
mkdir -p "TARGET/$dir"                                                                                                                                                                                                                                                       

# see: https://stackoverflow.com/questions/414164/how-can-i-select-random-files-from-a-directory-in-bash                                                                                                                                                                     
find "$dir" -maxdepth 1 -type f | sort -R | tail -n $cnt | while read file; do                                                                                                                                                                                               
  # copy the file                                                                                                                                                                                                                                                            
  cp "$file" "TARGET/$dir/"
done

E não se esqueça de tornar o script executável: chmod +x randomCopy.sh.

Substitua a string TARGETpelo seu diretório de destino ou use uma terceira opção de script.

Esta prova de conceito está sendo executada em meu diretório de teste, mas pode haver muito o que melhorar.

informação relacionada