复制随机文件夹的脚本

复制随机文件夹的脚本

我想实现一个我一直想做的小项目。我的桌面上有一个巨大的音乐库,我正在寻找一种方法/脚本来选择随机数量的文件夹(例如 25 张专辑),如果可行,将它们复制到我的汽车的 USB 驱动器上。我的完整愿景是编写一个能够执行以下步骤的脚本:

  1. 清除 USB 驱动器(它仅用于音乐)
  2. 随机选择专辑(数据量上限?固定数量?)
  3. 将所选内容复制到 USB 驱动器

这可以通过简单的脚本实现吗?我记得有些音乐组织者有这个选项,但我正在寻找更简单的无头服务器。

答案1

您可以使用 find 和 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"

答案2

下面的脚本应该可以完成这个工作:

#!/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. 在 head 部分,设置要选择的文件数,姓名闪存驱动器(脚本将找到其路径)和带有文件夹的源目录。
  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)
    

答案3

我用 Python 编写了一个脚本:

该脚本位于 GitHub Gist。下载

用法:

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

相关内容