Скрипт для копирования случайных папок

Я хотел бы реализовать небольшой проект, который я всегда имел в виду. У меня есть огромная музыкальная библиотека на рабочем столе, и я ищу способ / сценарий для выбора случайного количества папок (скажем, 25 альбомов) и, если это возможно, скопировать их на USB-накопитель для моей машины. В моем полном видении был бы сценарий, способный выполнить следующие шаги:

  1. Очистить USB-накопитель (он будет использоваться только для музыки)
  2. Случайный выбор альбомов (ограничение объема данных? фиксированный номер?)
  3. Скопировать выбор на USB-накопитель

Это выполнимо с помощью простого сценария? Я помню, что у некоторых организаторов музыки была такая возможность, но я искал что-то более простое для безголового сервера.

6
задан 23 May 2016 в 15:44

3 ответа

Вы могли использовать, находят и 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"
7
ответ дан 24 May 2016 в 01:44

Сценарий ниже должен сделать задание:

#!/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)

Это копирует каталоги с первого подуровня исходного каталога в целенаправленный флеш-накопитель.

Это - то, что, кажется, имеет большую часть смысла, начиная с рекурсивного копирования папок, наугад, вызывает большую разницу в папке - подуровни числа и размер. Я добавил его, тем не менее, как вторую опцию в нижней части этого ответа.

Как использовать

  1. Скопируйте сценарий в пустой файл, сохраните его как create_mediausb.py
  2. В главном разделе, определенном номер файлов, которые будут выбраны, название флеш-накопителя (сценарий найдет свой путь), и источник diectory с папками.
  3. Запустите скрипт с командой:

    python3 /path/to/create_mediausb.py 
    
  4. Если все хорошо работает, добавьте его к сочетанию клавиш: выберите: Параметры настройки системы> "Клавиатура"> "Ярлыки"> "Пользовательские Ярлыки". Нажмите "+" и добавьте команду:

    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)

Сценарий:

  1. Ищет путь к флеш-накопителю:

    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
    

    Если флеш-накопитель не найден, он заканчивается здесь

  2. Если диск был найден, он освобожден

    # empty the flash drive
    for item in os.listdir(targetdr):
        obj = (targetdr+"/"+item)
        try:
            shutil.rmtree(obj)
        except NotADirectoryError:
            os.remove(obj)
    
  3. Затем так как нам нужен целый список каталога, чтобы сделать соответствующий выбор наугад, мы создаем список прежде, чем сделать выбор:

    # list the source dirs
    srclist = []
    for dr in  os.listdir(sourcedr):
        fullpath = sourcedr+"/"+dr
        if os.path.isdir(fullpath):
            srclist.append([dr, fullpath])
    
  4. Самая интересная часть делает выбор. Мы выбираем случайный каталог, удаляем его из списка, чтобы предотвратить двойные выборы, затем выбрать другой наугад, удалить его, и так далее, пока мы не достигаем количества желаемых выборов:

    # copy the files
    for picked in random.sample(srclist, n_selection):
        shutil.copytree(picked[1], os.path.join(targetdr, picked[0]))
        srclist.remove(picked)
    
7
ответ дан 24 May 2016 в 01:44

Я сделал сценарий с Python:

Сценарий, в Сути GitHub. (Загрузка)

Использование:

python3 RandomCopier.py [source folder] [destination folder] [number to copy]

Метод копии:

Примечание: Это не скопирует файлов непосредственно в исходной папке, только файлы в подпапках его.

Скажите, исходная папка, src :

src
|- a
|  |- file_a
|  |- file_a_2
|
|- b
|  |- file_b
|
|- c
|  |- file_c
|
|- file_src

затем, папка назначения dest был бы, с 2 папками, случайным образом скопированными, как:

dest
|- a
|  |- file_a
|  |- file_a_2
|
|- c
|  |- file_c
1
ответ дан 24 May 2016 в 01:44

Другие вопросы по тегам:

Похожие вопросы: