我是一名专业音乐家,经常需要重命名20-30个.PDF文件列表,以便按照分数顺序排序。例如,我有一个文件列表,如:
Rolling Thunder Eb Clarinet - 4p.PDF
Rolling Thunder Flute 1 - 4p
Rolling Thunder Flute 2 - 4p
Rolling Thunder FULL SCORE - CONDENSED - 20p
Rolling Thunder Horn in F 1 - 3p
Rolling Thunder EDIT 9-7-15 Horn in F 2 - 3p
...
我需要将它们重命名,以便按照它们出现在分数中的顺序排序(在Finder中),即:
00 - Rolling Thunder FULL SCORE - CONDENSED - 20p
01 - Rolling Thunder Flute 1 - 4p
02 - Rolling Thunder Flute 2 - 4p
... etc.
我通过创建一个包含工具顺序的文本文件(以便根据需要修改各种上下文的顺序)来解决这个问题,例如:
Piccolo
Flute
Oboe
Clarinet
Bassoon
French Horn
...
然后启动Bash脚本以按此顺序查找文件:
while read line; do
find . -name "*$line*"
done < scoreorder.txt
我不确定如何在此基础上重命名文件。有人可以帮忙吗?
答案 0 :(得分:1)
假设目录中没有不相关的文件,可能是这样的。
要获取所有PDF文件的列表,只需printf
匹配的glob。
printf '%s\n' *.pdf
让我们将其传递给Awk脚本,该脚本将这些脚本映射到scoreorder.txt
的索引号。首先,将文件读入数组a
,并为我们读取的每个条目添加数字索引。
awk 'NR==FNR { a[++n] = $0; next } ...' scoreorder.txt -
当我们阅读NR==FNR
时,scoreorder.txt
将成立;脚本的其余部分将应用于我们从标准输入读取的行,来自上面的printf
。
... { m=0;
for(i=1; i<=n; ++i)
if ($0 ~ a[i])
if (m==0 || length(a[m]) < length(a[i])) m=i;
在每一行上,我们从最长匹配中选择索引(因此French Horn
优先于Horn
,无论它们在索引中的位置如何)。如果没有匹配,m
将为0。
printf("%i\t%s\n", m, $0); }'
这将产生“原始排序”,其中FULL SCORE
将具有前缀00(因为它与任何关键字都不匹配),例如Flute
文件的前缀为02.这足以对列表进行排序。
| sort -n |
现在我们只需要对行进行编号并稍微进行后处理以删除“原始排序”数字。
awk -F '\t' '{ printf "mv \"%s\" \"%02i - %s\"\n", $2, NR, $2 }'
此时的排序顺序仍略有偏差 - 第二个EDIT
文件名中的Horn
会使排序顺序失效。也许你只想修改你的命名约定,或者你想在.pdf
之前选择最后的数字作为辅助排序键。
输出是一个shell脚本,一旦你对它做了它应该做的事情感到满意就可以输出到sh
。这仍然是最后的剧本。
printf '%s\n' *.pdf |
awk 'NR==FNR { a[++n] = $0; next }
{ m=0;
for(i=1; i<=n; ++i)
if ($0 ~ a[i])
if (m==0 || length(a[m]) < length(a[i])) m=i;
printf("%i\t%s\n", m, $0); }' scoreorder.txt - |
sort -n |
awk -F '\t' '{ printf "mv \"%s\" \"%02i - %s\"\n", $2, NR, $2 }'
如果您的文件名包含双引号,制表符或换行符,则会变得更加棘手。我只是假设你没有。