我是新手,想弄清楚如何重命名目录中的一堆文件。我有数百个媒体文件,它们的文件名都遵循相同的语法:
year - title of movie.avi
我想编写一个脚本,从文件名开头删除年份和“ - ”,并将其附加到末尾。最终结果:
title of movie - year.avi
(或类似的东西。我并不真的需要破折号)
我遇到的类似下面的 for 循环的问题是,由于文件名中包含空格,所以我的脚本不断解析每个单词而不是每个完整的文件名。
for file in $(ls)
结果我并没有取得很大进展。
答案1
您可以使用rename
带有正则表达式的命令:
rename 's/(\d+) - (.*)\.avi/$2 - $1.avi/' *.avi
解释:
rename
- 命令(您可能必须安装它)s/<match>/<replacement>/
(替代命令).*avi
在所有.avi
文件上运行上述操作
匹配正则表达式:
(\d+)
匹配并捕获$1
一个或多个数字的组 ()-
匹配文字-
(.*)
匹配任何内容并捕获到组中 ($2
)\.avi
匹配.avi
(点被转义)
替代品:
$2 - $1.avi
- 粘贴第二组(标题),然后粘贴破折号,然后粘贴第一组(年份),然后粘贴文件扩展名
学习正则表达式,<3 正则表达式。避免使用 bash 循环遍历文件,因为将字符串拆分为标记很难理解且经常令人困惑,如果您不理解它们,您可能会忽略一些事情。
答案2
您还可以使用mmv
为此。首先使用以下命令安装它:
sudo apt install mmv
然后从包含文件的目录运行:
mmv -n '???? - *.avi' '#5 - #1#2#3#4.avi'
第一个表达式 ( '???? - *.avi'
) 匹配以 4 个字符(a?
代表年份的 4 位数字)开头,后跟由空格包围的连字符 ( -
) 和任意数量的任意字符(*
代表标题)并以 结尾的任何文件.avi
。
第二个表达式('#5 - #1#2#3#4.avi'
)获取每个匹配项(形式为#n
)并按所示方式排列以实现所需的结果,即首先是图块,然后是年份,并用 分隔-
。
上述命令将显示将要进行的更改的预览。如果您对它们感到满意,请运行不带标志的命令-n
。
答案3
仅在 bash 中:
for f in *.avi; do
t="${f#*- }"; t="${t%.*}"; echo mv -n -- "$f" "${t} - ${f%% *}.${f##*.}";
done
答案4
您可以在 Bash 或 Korn Shell 中执行的一件事是更改内部字段分隔符。默认情况下,$IFS 包括空格、制表符和回车符或换行符。您可以将 IFS 更改为仅在行末使用换行符。
例子:
ORIGINAL_IFS="${IFS}"
IFS=$(echo "\n")
for LOOP in $(ls)
do
print ${LOOP}
done
IFS="${ORIGINAL_IFS}"
除了在循环的该阶段使用 print 之外,您还可以使用 awk 或 cut 并从行首获取年份。
您可能需要在继续脚本的下一部分之前将 IFS 重置为其原始值,以防它影响其他逻辑。