我有很多(大约 6000 个!)mp3,我想根据文件名将它们转储到子目录中。目前它们都在一个子目录中。(一些艺术家的目录中已经有一些目录,我不想碰这些目录中的文件,但是可以重复覆盖现有文件)。
我认为最简单的方法是根据文件名创建一个子目录,因为所有文件都命名为 artist.artist.album.track.mp3。
经过一番搜索我得出了以下结论:
for x in ./*.mp3; do awk x="${x}" -F. '{split(x,a,"."); mkdir a[1]; mv x a[1]/}'; done
但是它告诉我存在语法错误和未终止的正则表达式:
awk: cmd. line:1: x=./Dizzee.Rascal.Radio.1.Live.Lounge.03.That.s.Not.My.Name.mp3
awk: cmd. line:1: ^ syntax error
awk: cmd. line:1: x=./Dizzee.Rascal.Radio.1.Live.Lounge.03.That.s.Not.My.Name.mp3
awk: cmd. line:1: ^ unterminated regexp
awk: cmd. line:1: x=./Dizzee.Rascal.Ultimate.Streetdance.CD1.03.Flex.Dave.Spoon.Mix.mp3
awk: cmd. line:1: ^ syntax error
awk: cmd. line:1: x=./Dizzee.Rascal.Ultimate.Streetdance.CD1.03.Flex.Dave.Spoon.Mix.mp3
awk: cmd. line:1: ^ unterminated regexp
我认为这是因为文件名没有在引号内给出,但我不是 100% 确定?
有人可以帮忙吗?如果您也可以打印出进度,则可以获得加分。
答案1
为什么awk
?好吧,我们假设一下awk
……
x="${x}"
在您想要成为程序之前需要-v
(即-v x="${x}"
),否则它会被解释为程序。这就是您收到语法错误的原因。- 您的实际程序并不是按每行输入执行,而是按每次
awk
调用执行;因此您需要BEGIN
。 - 您可能不是这个意思
a[1]
;也许a[2]
。 - 不加引号
/
(即在上下文中不加引号awk
,而不是在 shell 中)是错误的。 mkdir
和mv
不是 中的操作awk
。我认为它们被解释为(空)变量。有system
操作,您可以使用它。但由于您需要传递任意文件/目录名称,因此会出现以下问题:- 适当的引用;
- 命令注入漏洞(文件名的一部分可能被解释为命令)。
我说忘掉awk
这里。下面的代码假设您想要使用前两个点分隔的段来命名目录。注意:
- 名为 的文件
foo.mp3
将触发错误mkdir -p ./foo.mp3/
; - 修改代码非常容易,因此可以使用一个、三个或另一个固定的点分隔段的数量。
for x in ./*.mp3; do
# remove leading ./
d="${x#./}"
# first segment
d1="${d%%.*}"
# remainder
d="${d#*.}"
# second segment
d2="${d%%.*}"
#result
d="./${d1}.${d2}/"
mkdir -p "$d" && mv "$x" "$d"
done
无论如何我建议创建一个单独的目录来使用:
cp -al my_music/ my_music_copy/
cd my_music_copy/
这使用硬链接,因此速度很快,几乎不占用额外的磁盘空间。处理 中的目录结构my_music_copy/
。如果搞砸了,您可以随时删除my_music_copy/
并重新开始。只有当您确定 中的所有内容都已就位后my_music_copy/
,才可以删除my_music/
并重命名my_music_copy/
为my_music/
。
如果没有固定的需要一定数量的段和一些启发式方法,请尝试vidir
;类似这样的操作:
find . -maxdepth 1 -type f -iname '*.mp3' | EDITOR=vi vidir -
然后,您可以使用所选编辑器的“搜索和替换”功能可靠地创建所需的目录(例如,用 替换./Dizzee.Rascal.
;./Dizzee.Rascal/
但./Mozart.
用./Mozart/
和./W.A.Mozart.
替换./W.A.Mozart/
,或者也可以用 替换./Mozart/
)。请参阅我的这个答案。
优点:
- 如果出现问题,请不要保存文件。中止并重新开始。
- 您不需要一次处理所有文件。您未触碰的文件(行)将不会被移动。处理一小部分以确保此部分正确;保存,退出编辑器。再次调用该命令以处理剩余文件。
- 您可以将数据复制到另一个工具(例如电子表格),在那里处理,粘贴回来,保存并退出。