实际上,这可以通过多种方式完成。我将展示如何在 中bash
,但前提是您在 Windows 上的 Ubuntu 上拥有 Bash 的东西。再次:
重击
假设您的音乐库是~/Music/
,所有艺术家文件夹都在其中,您接受将所有内容移至新文件夹,假设它尚不存在(因为如果您有一个名为“CoolSinger”的艺术家文件夹并且只是不小心您还有另一个名为“CoolSinger - CoolAlbum”的艺术家文件夹,错误地,会有问题......),并且除了您所说的之外没有涉及任何其他文件,shell脚本看起来像这样:
#!/bin/bash
mkdir ~/NewMusic/
for artistdir in ~/Music/*; do
artistname="$(basename "${artistdir}")"
for albumdir in "${artistdir}"/*; do
albumname="$(basename "${albumdir}")"
mv "${albumdir}" ~/NewMusic/"${artistname} - ${albumname}" 2>/dev/null
done
done
让我用人类来解释一下:
创建目标文件夹。然后,对于每个artist
(假设都是文件夹);遍历每个album
子文件夹,将其移动到新文件夹,顺便说一下,使用实际文件夹名称中的艺术家名称和文件夹名称对其进行重命名。如果一切顺利,这将导致:
- 具有原始子文件夹
~/Music/
名称的文件夹,但它们现在为空。
~/NewMusic
具有所需结构的文件夹。
- 如果艺术家文件夹是空的,shell 会尝试抛出错误,因为它会扩展为文字字符串(稍后解释),但不要担心,因为如果它是空的,那么任何事情都与它有关,所以你可以忽略它,附加
2>/dev/null
到命令中。但是,如果出现任何其他问题,它也会被静音。
如果你想,比如说,保留原始文件,and
拥有所有具有所需结构的副本,你应该将mv
命令更改为cp -R
一个。
而这一切都是为了一个脚本,在一个文件中。如果您想直接从命令行执行它,这会使得更改音乐库的文件夹名称有些棘手,它看起来像这样:
mkdir ~/NewMusic/; for artistdir in ~/Music/*; do artistname="$(basename "${artistdir}")"; for albumdir in "${artistdir}"/*; do albumname="$(basename "${albumdir}")"; mv "${albumdir}" ~/NewMusic/"${artistname} - ${albumname}"; done; done
并解释那里的一切:
mkdir
创建目录。
for A in B ; do C ; done
是一个循环。它循环遍历由 中的一个 IFS 字符分隔的每个字符串,并在执行时B
将其分配为变量的值。
A
C
- 请注意,脚本中的文本带有星号。shell 将带有星号的字符串扩展为它找到的与模式匹配的字符串。例如,如果您有一堆 Word 文档,键入
echo *.docx
将扩展到当前文件夹中与该结尾匹配的每个名称(在另一种情况下为echo /path/*.docx
)。
- 因此,对于指定目录中的每个文件夹,分配(为每个艺术家文件夹一次)以
artistname
指定文件(在本例中为文件夹)的基本名称作为其值的变量。所以,basename /path/to/anything
返回anything
。
- 在另一个
for
循环的帮助下,对艺术家目录中的每个元素执行操作,将其重命名为指定的名称,如果新名称在另一个目录中,它将把它移到那里。
- 同样,
2>/dev/null
重定向用于将所有输出重定向stderr
到 void。stdout
但是,如果有的话,仍然会打印输出。
一些重要说明
- 我不知道Windows 上 Ubuntu 上的 Bash的 shell 是否检测
/dev/null
为标准 UNIX 机器具有的特殊字符文件。可能是这样,否则它不会与这么多东西兼容。
- 仅当您在 Windows 10 中的 Windows 上安装了Bash on Ubuntu 时。如果我没记错的话,使用它的机会是通过周年更新实现的。如果您有更新,但没有
bash
,我建议您安装它。互联网上有几个指南。
- 关于文件夹结构。我怀疑与
/dev/null
POSIX 文件夹结构相同:它遵循它,因为它不仅是Bash on Windows,而且是Bash on Ubuntu on Windows。