我需要一个执行以下操作的bash脚本: 对于文件夹及其子文件夹中存在的某种类型的每个文件,它都会包含一个序号(4位),后跟一个分隔符( - )
例如,我有:
/Queen/(1986) A Kind of Magic/01.One vision.mp3
/Queen/(1986) A Kind of Magic/02.A kind of magic.mp3
/Queen/(1986) A Kind of Magic/cover.jpg
/Queen/(1991) Innuendo/01.Innuendo.mp3
/Queen/(1991) Innuendo/02.Headlong.mp3
/Queen/(1991) Innuendo/cover.jpg
/Queen/(1991) Innuendo/booklet.pdf
我希望在脚本中有以下内容:
/Queen/(1986) A Kind of Magic/0001-01.One vision.mp3
/Queen/(1986) A Kind of Magic/0002-02.A kind of magic.mp3
/Queen/(1986) A Kind of Magic/cover.jpg
/Queen/(1991) Innuendo/0003-01.Innuendo.mp3
/Queen/(1991) Innuendo/0004-02.Headlong.mp3
/Queen/(1991) Innuendo/cover.jpg
/Queen/(1991) Innuendo/booklet.pdf
请注意我在文件夹名称中的文件名和括号中有空格! 我怎样才能做到这一点?我试过mac automator但没有成功! :(
谢谢
答案 0 :(得分:1)
创建以下bash脚本并在音乐集的基目录中执行它。它将使用包含空格,括号,单引号和双引号,其他奇怪字符的文件和目录名称,但不,名称包含换行符或真正奇怪的字符。您可以自定义它,为start_dir
提供不同的值,或更改格式规范%s/%04u-%s
,目前包含%s
(目录名称)%04u
(编号索引,格式化)作为零填充的四位整数)和%s
(文件名),由/
和-
分隔。
#!/bin/bash
start_dir="."
find "$start_dir" -name '*.mp3' -type f \
|sort \
|while read name; do
((i++))
mv -i "$name" \
"$(printf '%s/%04u-%s' "$(dirname "$name")" $((i)) "$(basename "$name")")"
done
<强>说明:强>
Socowi的答案与我的非常相似。差异是(1)他需要bash 4.0,默认情况下不安装在Mac上。我不。 (2)他的脚本将使用包含换行符的文件名(非常罕见的场合)。我的不会。 (3) 如果所有mp3文件(包括子目录)的名称总长度超过262144字节,则他的脚本将失败;我会说如果你有超过6000个文件会发生这种情况。我将使用任意数量的文件。
(注意mapfile
- 爱好bash从业者:我知道使用mapfile
可能是一种生成索引而不明确创建$i
的智能方法,但是(i)没有需要大型数组mapfile
会创建和(ii)在解析传递给mv
回调的命令行时,无论如何我都需要一个变量。)
答案 1 :(得分:0)
以下脚本为当前目录下的所有mp3文件添加四位数前缀,并且应该适用于所有可能的文件名。
#! /bin/bash
shopt -s globstar nullglob
n=0
for f in **/*.mp3; do
(( ++n ))
b="$(basename "$f")"
mv -i "$f" "${f%"$b"}/$(printf '%04d' "$n")-$b"
done
globstar **
需要bash&gt; 4.0据我所知,它没有预先安装在mac上(请与bash --version
联系)。但我听说有很多方法可以安装更新的bash版本。
文件的编号顺序取决于您的区域设置。 Bash根据**/*
按排序方式展开LC_COLLATE
。至少LC_COLLATE=en_US.UTF-8
个文件按字母顺序编号,我们不必担心名称冲突 - 保证不会发生覆盖。