【问题标题】:Rename subfolder: add leading word from parent folder重命名子文件夹:从父文件夹添加前导词
【发布时间】:2017-07-16 10:52:35
【问题描述】:

我在Artist 文件夹和Album 子文件夹中组织了一个大型音乐库:

Artist 1
- Album A
-- File 1
-- File 2
- Album B
-- File 1
-- File 2
Artist 2
- Album C
-- File 1
-- File 2
- Album D
-- File 1
-- File 2

现在我想通过添加 Artist 名称作为前缀来重命名所有 Album 文件夹并将所有 Album 文件夹移动到 root 目录中,如下所示:

Artist 1 - Album A
- File 1
- File 2
Artist 1 - Album B
- File 1
- File 2
Artist 2 - Album C
- File 1
- File 2
Artist 2 - Album D
- File 1
- File 2

最好的方法是什么?我试着用 Total Commander 来做,但我不明白。或者也许是外壳,mp3tag?我使用 Windows 10。 谢谢!

【问题讨论】:

  • 好吧,我自己找到了答案。最好的方法是使用mp3tag 工具。您可以创建新文件夹并在其中复制文件。 1. 选择Converter > Tag - Filename 2. 输入:E:\%artist% - %album%\$num(%track%,2) - %title% 你会收到一个带有Artist - Albumname\01 - File.mp3的目录

标签: shell directory rename subdirectory total-commander


【解决方案1】:

实际上,这可以通过多种方式完成。我将在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

以及对所有内容的解释:

  1. mkdir 创建目录。
  2. for A in B ; do C ; done 是一个循环。它循环遍历由B 中的一个 IFS 字符分隔的每个字符串,并将其分配为变量A 的值,同时执行C
    • 请注意,脚本中的文本带有星号。 shell 将带有星号的字符串扩展为它找到的与模式匹配的字符串。例如,如果您有一堆 Word 文档,输入 echo *.docx 将扩展为当前文件夹中与该结尾匹配的每个名称(在另一种情况下,echo /path/*.docx)。
  3. 因此,对于指定目录中的每个文件夹,分配(每个艺术家文件夹一次)变量artistname,并将指定文件的基本名称(在本例中为文件夹)作为其值。所以,basename /path/to/anything 返回anything
  4. 在另一个for 循环的帮助下,对艺术家目录中的每个元素执行操作,按照指定重命名它,如果新名称在另一个目录中,它会将其移动到那里。
    • 同样,2>/dev/null 重定向用于将 stderr 中的所有输出重定向到 void。不过,stdout 中的输出仍会打印,如果有的话。

一些重要说明

  • 我不知道 Windows 上的 Ubuntu 上的 Bash 的 shell 是否将 /dev/null 检测为标准 UNIX 机器所具有的特殊字符文件。 可能确实如此,否则它不会与这么多东西兼容。
  • 如果您在 Windows 10 中安装了 Bash on Ubuntu on Windows。如果我没记错的话,使用它的机会是通过周年更新实现的。如果你有更新,但没有bash,我建议你安装它。互联网上有几个关于这方面的指南。
  • 关于文件夹结构。我怀疑/dev/null 与 POSIX 文件夹结构相同:它遵循它,因为它不仅仅是 Windows 上的 Bash,而是 Ubuntu 上的 Bash窗户

【讨论】:

  • 感谢您的扩展回答。因为我不在 linux 上并且没有使用 bash 的经验,所以我肯定需要时间来测试这种方式......也许它会起作用,我会看到的。再次感谢。
【解决方案2】:

我自己找到了答案。最好的方法是使用 mp3tag 工具。您可以创建新文件夹并在其中复制文件。

  1. 选择转换器 > 标记 - 文件名

  2. 输入:

    E:\%artist% - %album%\$num(%track%,2) - %title%
    

您将收到包含 Artist - Albumname\01 - File.mp3 的目录

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2016-07-24
    • 1970-01-01
    相关资源
    最近更新 更多