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

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

mv ./*.mp4 ./subdir/

但是如果我想改变这些 files 的扩展而不是移动呢?我希望存在这样的语法:

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

在这里,括号确实捕获了匹配的字符串,并且 @1 将被该字符串替换。

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

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

我不太确定模式匹配在 shell 中是如何工作的,所以我怀疑是否有比上述 for 循环更简单的解决方案。

回答1

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' './$1.webm'

回答2

使用 perl rename

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

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

默认情况下未预安装:

  • MacOS:使用 https://brew.shbrew install rename
  • Ubuntu:apt install rename

相似文章