仅使用内置工具修剪bash中的文件名(无重命名命令)

仅使用内置工具修剪bash中的文件名(无重命名命令),bash,Bash,我有表单的文件名 word-123_AnotherWord--asdf_12345.mp4 word-123_AnotherWord-_asdf-12345.mp4 word-123_AnotherWord-asdf--12345.mp4 word-123_AnotherWord-asdf_-12345.mp4 …我希望将其修剪为仅包含最后11个字符和扩展名 我目前的尝试如下所示: $ for i in *.mp4 ; do mv "$i" "${/.*?(.{1,11}\.m

我有表单的文件名

word-123_AnotherWord--asdf_12345.mp4
word-123_AnotherWord-_asdf-12345.mp4
word-123_AnotherWord-asdf--12345.mp4
word-123_AnotherWord-asdf_-12345.mp4
…我希望将其修剪为仅包含最后11个字符和扩展名


我目前的尝试如下所示:

$ for i in *.mp4 ; do 
      mv "$i" "${/.*?(.{1,11}\.mp4)$/}";
done
但我给了我一个错误:

bash:${/*?(.{1,11}.mp4)$/}:错误的替换

知道为什么吗

这个问题是对这个问题的继续,但答案只有在我的电脑上本地工作,我没有在我的服务器上远程工作


提前谢谢

在语法
${var/pattern/replacement}
中,用法“${/*?(.{1,11}\.mp4)$/}”有几处错误:

  • 首先,
    var
    不是可选的,而是强制性的
  • 其次,
    模式
    需要以glob格式给出,而不是regex格式。如果你想要更华丽的表达方式,请使用
  • 第三,除非目的是删除与表达式匹配的部分,否则最后的
    /
    实际上应该包含一些内容
如果您想修剪每个名称的最后15个字符以外的所有字符(扩展名为11+4),这很简单:

for i in *.mp4; do
  mv "$i" "${i:${#i}-15}"
done

现在,如果您真的想使用正则表达式:

name_re='.{1,11}\.mp4$'
for i in *.mp4; do
  [[ $i =~ $name_re ]] && mv -- "$i" "${BASH_REMATCH[0]}"
done

你到底想让代码做什么?…也就是说:对于知道bash为什么失败的人来说,这是显而易见的。不清楚它将如何改变,因为你的写作意图不清楚。但是如何改变名称呢?请给出一个输入名称和输出名称的示例。是的,这是一个继续:,但答案是那里只在本地我的电脑上工作,我没有远程在我的服务器上工作!如果需要回答,新问题中应包含先前相关问题的信息。此外,你应该在问题中包括一个链接,而不仅仅是在评论中。>最后的
/
实际上应该包含一些内容。请你澄清这一点好吗?比如我的案例?@SomeOne,因为你想做的实际上不是替换,
${var/pattern/replacement}
根本不是正确的值。但是,
${var/pattern/}
只是在模式出现时删除它,因为它不使用任何内容替换它,而不是隔离模式。因此,如果您将regex更新为有效的shell模式,即使这样,此代码也会做错误的事情,因为它将删除匹配的内容,并将文件重命名为删除后留下的内容,而不是将文件重命名为匹配的内容。