我想实现一个我一直想做的小项目。我的桌面上有一个巨大的音乐库,我正在寻找一种方法/脚本来选择随机数量的文件夹(例如 25 张专辑),如果可行,将它们复制到我的汽车的 USB 驱动器上。我的完整愿景是编写一个能够执行以下步骤的脚本:
- 清除 USB 驱动器(它仅用于音乐)
- 随机选择专辑(数据量上限?固定数量?)
- 将所选内容复制到 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)
它将源目录的第一个子级的目录复制到目标闪存驱动器中。
这似乎是最有意义的,因为递归地复制文件夹,随机,导致文件夹大小和子级别数量有很大差异。 尽管如此,我还是将其作为第二个选项添加到此答案的底部。
如何使用
- 将脚本复制到一个空文件中,另存为
create_mediausb.py
- 在 head 部分,设置要选择的文件数,姓名闪存驱动器(脚本将找到其路径)和带有文件夹的源目录。
使用以下命令运行脚本:
python3 /path/to/create_mediausb.py
如果一切正常,请将其添加到快捷键:选择:系统设置>“键盘”>“快捷键”>“自定义快捷键”。单击“+”并添加命令:
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)
剧本:
查找闪存驱动器的路径:
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
如果找不到闪存驱动器,则到此结束
如果找到驱动器,则清空它
# empty the flash drive for item in os.listdir(targetdr): obj = (targetdr+"/"+item) try: shutil.rmtree(obj) except NotADirectoryError: os.remove(obj)
那么,由于我们需要整体目录列表随机进行适当的选择,我们在进行选择之前创建一个列表:
# list the source dirs srclist = [] for dr in os.listdir(sourcedr): fullpath = 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)
答案3
我用 Python 编写了一个脚本:
用法:
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