我正在寻找一种通过删除两点之间的文本来重命名一批视频的方法。具体来说,我想删除第 6 个字符之后的所有内容,直到最后一个“LabelMe--”。
0001--LabelMe--A005_01241110_C001--LabelMe-- --Interview--Man in library.mov
0002--LabelMe--A005_01241110_C002--LabelMe-- --Broll--Man looking at books.mov
0003--LabelMe--A005_01241111_C003--LabelMe-- --Broll--messed up--LabelMe-- --Broll--Sitting at table.mov
我正在尝试使用 Apple 的 Automator 服务来做到这一点。右键单击一堆文件并选择要清理名称的服务。我找到了一段代码,但不确定我是否正确使用它。
for f in "$@"
do
echo sed -e 's/\(--LabelMe).*\(LabelMe--)/\1\2/'
done
答案1
使用 (perl) 重命名。我不了解 Apple,但 Linux 发行版大多附带两个版本的重命名。 Perl rename 是更强大的一种。
首先,使用该标志运行命令-n
,这会执行“空运行”,并且不进行任何更改。
$ rename 's/(.{6}).*LabelMe--/$1/' 000* -n
0001--LabelMe--A005_01241110_C001--LabelMe-- --Interview--Man in library.mov -> 1110_C --Interview--Man in library.mov
0002--LabelMe--A005_01241110_C002--LabelMe-- --Broll--Man looking at books.mov -> 1110_C --Broll--Man looking at books.mov
0003--LabelMe--A005_01241111_C003--LabelMe-- --Broll--messed up--LabelMe-- --Broll--Sitting at table.mov -> messed --Broll--Sitting at table.mov
一旦您对结果感到满意,就可以真正运行它,即rename 's/(.{6}).*LabelMe--/$1/' 000*
解释
rename 's/foo/bar/' 000*
:此格式将搜索foo
正则表达式并将其替换为bar
.它将对与 glob 匹配的所有文件进行操作000*
。(.{6}).*LabelMe--
:这是您正在搜索的正则表达式。您正在寻找任何角色的六个.{6}
,并将其放入捕获组中(.{6})
。此后,您可以.*
在查找之前拥有任何字符LabelMe--
。$1
:这就是您将替换上面字符串的内容。指的是上面$1
匹配组的内容。(.{6})
其余的将不会被替换,即您删除前六个字符之后直到(包括)的所有内容LabelMe--
。
答案2
这个网站上有很多关于使用 shell 循环重命名文件的问题,还有一些关于使用sed
它的问题。 (例如这,这)
您需要使用sed
管道传递文件名并使用命令替换来捕获结果,如下所示:
mv "$f" "$(echo "$f" | sed -e '...' )"
您使用的命令sed
需要进行一些修复:首先,您引用了左括号,但没有引用右括号,因此分组不起作用。另外,我不确定您为什么要将LabelMe
片段放回到文件名中。如果您想删除它们,只需跳过分组和\N
引用:
's/--LabelMe.*LabelMe--//'
完整来说:
for f in "$@"
do
mv "$f" "$(echo "$f" | sed -e 's/--LabelMe.*LabelMe--//' )"
done
另一种方法是使用 shell 的参数替换来执行相同的操作。这种替换${par/pattern/replacement}
是非标准的,但在许多 shell 中都支持:
for f in "$@"
do
mv "$f" "${f/--LabelMe*LabelMe--/}"
done
(请注意,这不是正则表达式,因此“任何内容”的语法只是*
, 而不是.*
)