você pode usar find e shuf:
#!/bin/bash
SOURCE="path/to/source"
DESTINATION="path/to/destination"
COUNT=25
rm -r "${DESTINATION}/"*
find "$SOURCE" -mindepth 2 -maxdepth 2 -type d|shuf -n $COUNT|xargs -d'\n' -I{} cp -r "{}" "$DESTINATION"
Eu gostaria de realizar um pequeno projeto que sempre tive em mente. Eu tenho uma vasta biblioteca de músicas na minha área de trabalho e estou procurando uma maneira / script para selecionar uma quantidade aleatória de pastas (digamos, 25 álbuns) e, se possível, copiá-las em uma unidade USB para o meu carro. Minha visão completa seria um script capaz de seguir estes passos:
Isso é possível através de um script simples? Eu lembro que alguns organizadores de música tinham essa opção, mas eu estava procurando por algo mais simples para um servidor sem cabeçalho.
você pode usar find e shuf:
#!/bin/bash
SOURCE="path/to/source"
DESTINATION="path/to/destination"
COUNT=25
rm -r "${DESTINATION}/"*
find "$SOURCE" -mindepth 2 -maxdepth 2 -type d|shuf -n $COUNT|xargs -d'\n' -I{} cp -r "{}" "$DESTINATION"
O script abaixo deve fazer o trabalho:
#!/usr/bin/env python3
import random
import os
import subprocess
import shutil
# set the desired number of folders to pick below
n_selection = 5
# set the name of the flash drive below
flashdr = "Lexar"
# set the source directory (with media folders) below
sourcedr = "/path/to/mediafiles"
# ---
try:
targetdr = [l.split("part ")[-1] for l in subprocess.check_output("lsblk")\
.decode("utf-8").splitlines()if l.endswith(flashdr)][0]
except IndexError:
pass
else:
# empty the flash drive
for item in os.listdir(targetdr):
obj = os.path.join(targetdr, item)
try:
shutil.rmtree(obj)
except NotADirectoryError:
os.remove(obj)
# list the source dirs
srclist = []
for dr in os.listdir(sourcedr):
fullpath = os.path.join(sourcedr, dr)
if os.path.isdir(fullpath):
srclist.append([dr, fullpath])
# copy the files
for picked in random.sample(srclist, n_selection):
shutil.copytree(picked[1], os.path.join(targetdr, picked[0]))
srclist.remove(picked)
Copia diretórios do primeiro subnível do diretório de origem para o flash drive desejado.
Isto é o que parece fazer mais sentido, uma vez que recursivamente copiando pastas, aleatoriamente , causa uma grande diferença em sub-níveis de tamanho de pasta e número. Eu adicionei, no entanto, como uma segunda opção na parte inferior desta resposta.
create_mediausb.py
Execute o script com o comando:
python3 /path/to/create_mediausb.py
Se tudo funcionar bem, adicione-o a uma tecla de atalho: escolha: Configurações do sistema > "Teclado" > "Atalhos" > "Atalhos personalizados". Clique no botão "+" e adicione o comando:
python3 /path/to/create_mediausb.py
#!/usr/bin/env python3
import random
import os
import subprocess
import shutil
n_selection = 5
flashdr = "Lexar"
sourcedr = "/home/jacob/Bureaublad/GW_site_nafestival_2015/pix/general"
try:
targetdr = [l.split("part ")[-1] for l in subprocess.check_output("lsblk")\
.decode("utf-8").splitlines()if l.endswith(flashdr)][0]
except IndexError:
pass
else:
# empty the flash drive
for item in os.listdir(targetdr):
obj = os.path.join(targetdr, item)
try:
shutil.rmtree(obj)
except NotADirectoryError:
os.remove(obj)
# list the source dirs
srclist = []
for root, dirs, files in os.walk(sourcedr):
for dr in dirs:
srclist.append([dr, os.path.join(root, dr)])
# copy the files
for picked in random.sample(srclist, n_selection):
shutil.copytree(picked[1], os.path.join(targetdr, picked[0]))
srclist.remove(picked)
O script:
Procura o caminho para o pen drive:
try:
targetdr = [l.split("part ")[-1] for l in subprocess.check_output("lsblk")\
.decode("utf-8").splitlines()if l.endswith(flashdr)][0]
except IndexError:
pass
Se a unidade flash não for encontrada, ela terminará aqui
Se a unidade foi encontrada, ela é esvaziada
# empty the flash drive
for item in os.listdir(targetdr):
obj = (targetdr+"/"+item)
try:
shutil.rmtree(obj)
except NotADirectoryError:
os.remove(obj)
Então, como precisamos da lista de diretórios para fazer uma seleção apropriada aleatoriamente, criamos uma lista antes de fazer a seleção:
# list the source dirs
srclist = []
for dr in os.listdir(sourcedr):
fullpath = sourcedr+"/"+dr
if os.path.isdir(fullpath):
srclist.append([dr, fullpath])
A parte mais interessante é fazer a seleção. Escolhemos um diretório aleatório, o removemos da lista para evitar escolhas duplas, depois escolhemos outro aleatoriamente, removemos e assim por diante, até alcançarmos o número de escolhas desejadas:
# copy the files
for picked in random.sample(srclist, n_selection):
shutil.copytree(picked[1], os.path.join(targetdr, picked[0]))
srclist.remove(picked)
Eu fiz um script com o Python:
O script, no GitHub Gist. ( Transferir )
Uso:
python3 RandomCopier.py [source folder] [destination folder] [number to copy]
O método de cópia:
OBSERVAÇÃO: Ele não copiará os arquivos diretamente na pasta de origem, somente aqueles em subpastas.
Diga, a pasta de origem, src
is:
src
|- a
| |- file_a
| |- file_a_2
|
|- b
| |- file_b
|
|- c
| |- file_c
|
|- file_src
então, a pasta de destino dest
seria, com 2 pastas copiadas aleatoriamente, como:
dest
|- a
| |- file_a
| |- file_a_2
|
|- c
| |- file_c