Shell 模式:重复使用匹配的字符串(文件名的一部分)

Shell Patterns: re-use matched string (part of the filename)

我有一个目录,里面有 .mp4 个文件,还有另一个目录 subdir。我知道我可以通过 运行 以下命令将所有这些文件移动到 subdir

mv ./*.mp4 ./subdir/

但是如果我想更改这些文件的扩展名而不是移动怎么办?我希望存在这样的语法:

mv ./(*).mp4 "./@1.webm"

此处,括号确实捕获匹配的字符串,@1 将被该字符串替换。

当然,我只是编了这样的语法,那个命令是行不通的。

所以,这里有一个问题:如何重复使用匹配的模式?如果没有类似的语法,我应该使用这个任务的什么解决方案?在您提出建议之前:我确实知道一个,通过使用循环 for f in ./*.mp4 ; do mv "$f" "${f/.mp4/.webm}" ; done,但我希望看到比那个更紧凑的解决方案。

我不太清楚,模式匹配在 shell 中是如何工作的,所以我怀疑,有没有比上面提到的 for 循环更简单的解决方案。

用 perl rename

rename -n 's{(.+)\.mp4}{./subdir/.webm}' *.mp4

如果看起来正确,请删除 -n 标志。

这不是默认的pre-installed:

  • MacOS:使用 Homebrewbrew install rename
  • Ubuntu: apt install rename

zsh 让您可以缩短循环。

# Compare to
# for f in ./*.mp4 ; do mv "$f" "${f/.mp4/.webm}" ; done
for f (./*.mp4) mv "$f" "$f:r.webm"

它还提供了 zmv 命令(模仿@glennjackman 的回答中的 Perl 脚本)。

autoload zmv
zmv './(*).mp4' './.webm'