在bash中删除文件的双重扩展名

15

我熟悉重命名,但我想知道重命名是否适用于删除重复的扩展名?

假设我有几个文件,它们的名称如下:

  • picture2.jpg.jpg
  • picture9.jpg.jpg
  • picture3.jpg.jpg
  • picture6.jpg.jpg

如何删除重复的扩展名?

最终结果:

  • picture2.jpg
  • picture9.jpg
  • picture3.jpg
  • picture6.jpg
3个回答

20

假设:

  • 您只想在当前工作目录中执行此操作(非递归)
  • 双扩展名的格式恰好为.jpg.jpg

那么以下脚本将起作用:

#!/bin/bash

for file in *.jpg.jpg
do
    mv "${file}" "${file%.jpg}"
done

解释:

  • ${file%.jpg}:这部分被称为参数替换
  • 来自同一来源:"${var%Pattern} 从$var中删除与$Pattern最后匹配的最短部分。"
  • 请注意,这里提到的“模式”被称为globbing,与正则表达式在重要方面不同

使用此脚本的方法:

  • 在该目录中创建一个名为clean_de.sh的新文件
  • 通过chmod +x clean_de.sh将其设置为可执行文件
  • 然后通过./clean_de.sh运行它

警告:

如@gniourf_gniourf所指出,如果您的mv支持,则使用-n选项。

否则,如果您在同一目录中有a.jpga.jpg.jpg,它将重命名a.jpg.jpga.jpg并覆盖已存在的a.jpg,而不发出警告。


这正是我所需要的,谢谢。我猜测是 %\ 进行了更改? - DᴀʀᴛʜVᴀᴅᴇʀ
如果你的mv命令有-n选项(不覆盖选项),你可以使用它,以防目标文件已经存在。 - gniourf_gniourf

5
一行重命名命令应该足以满足您的需求(至少对于您的情况而言):
rename 's/\.jpg\.jpg$/.jpg/' *.jpg.jpg

1

这里有一个更一般化但仍然简单的解决方案:

for oldName in `find . -name "*.*.*"`; do newName=`echo $oldName | rev | cut -f2- -d'.' | rev`; mv $oldName $newName; done

简短说明:
find . -name "*.*.* - 这将递归查找仅带有重复扩展名的文件

echo $oldName | rev | cut -f2- -d'.' | rev - 技巧在于这里:rev命令对字符串进行反转,因此现在您可以看到,您想要从第一个点开始的整个文件名。(gpj.gpj.fdsa)

mv $oldName $newName - 实际重命名文件

发布说明:由于这是一个简单的一行脚本,您可能会发现未处理的情况。文件名中带有额外的点、超深的目录结构等。


这将覆盖同名的非双后缀文件。如果目录包含image.jpg.php和image.jpg.jpg,则第一个文件将被删除。 - Lucent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接