如何将所有包含 mp3 的目录移动到另一个目录?

如何将所有包含 mp3 的目录移动到另一个目录?

我的计算机(Ubuntu 22.04)上有很多包含 MP3 文件的目录,例如我的/home、、/data某些分区等。我想通过将所有这些目录(大多数目录以音乐专辑名称命名......)移动到一个 MP3 目录中来重新分组/合并它们。

我知道要查找.mp3文件 ( find -iname '*.mp3') 中的谁,也知道如何移动find( -exec mv) 找到的文件。但是,我不知道如何移动包含找到的数据的目录。

任何想法?

答案1

您可以使用以下 bash 管道:

find /path/to/src -iname '*.mp3' -type f -printf '%h\0' |
    perl -0e 'print sort{length($b)<=>length($a)}keys%{{map {$_,1}<>}}' |
    xargs -0 echo mv --backup=t -t /path/to/dst

它执行以下操作:

  • \0并且-0将使用空分隔符而不是换行符来处理奇怪的目录名称。
  • find /path/to/src列出以下所有内容src
    • -iname '*.mp3'.mp3扩展的过滤器
    • -type f以某种方式排除带有该扩展名的文件夹
    • -printf '%h\0'获取文件所在的目录
  • perl -0e 'print ...'运行脚本:
    • sort{length($b)<=>length($a)}通过将较长的路径移至顶部来避免错误,以便子目录在其父目录之前移动
    • keys%{{map {$_,1}<>}}删除重复项,即当一个目录有两个或多个.mp3文件时
  • xargs获取每个输入行(即目录)并将其作为参数提供给命令
    • echo你应该在检查这是你想要的之后删除它
    • mv -t /path/to/dst将文件移动到目标。-t让我们在源文件系统路径之前指定目标目录,以便将xargs路径放在末尾。
      • --backup=t当不同位置有两个同名的目录时,对目录进行编号

即使父目录包含 ,也会先将子目录移出.mp3。如果您(像@PeterCordes)想要更改此行为,只需在 perl 脚本中交换$a$b即可。这将反转排序,以便先移动父目录。有关不再存在的父目录的其余错误可以忽略或用最后的 来消除2>/dev/null。感谢@Raffa 所做的许多改进。

示例设置

./src
./src/a
./src/a/a
./src/a/a/a
./src/a/a/a/a.mp3
./src/a/a.mp3
./src/d
./src/d/other.txt
./src/helloworld
./src/helloworld/c.mp3
./dst

示例结果

./src
./src/d
./src/d/other.txt
./dst
./dst/a
./dst/a/a
./dst/a/a.mp3
./dst/a.~1~
./dst/a.~1~/a.mp3
./dst/helloworld
./dst/helloworld/c.mp3

相关内容