Contents

使用bash向文件添加扩展名

1. 概述

有时,我们需要修复大量文件的扩展名。bash 是一个很好的工具,可以帮助我们相对轻松地实现这一目标。 在本教程中,我们将了解如何快速准确地做到这一点。

2. 简单循环

如果我们需要不加选择地为给定目录中的所有文件添加扩展名,我们可以使用一个简单的 for 循环和mv命令来做到这一点:

$ for f in *; do mv "$f" "$f.jpg"; done

该解决方案虽然非常简洁,但也有一些缺点。如果某些文件已经具有扩展名怎么办?或者也许某些文件不是我们想要修复的类型?我们将一个接一个地处理这些问题。

3. 选择没有扩展名的文件

在现实生活中,我们可以在一个目录中拥有各种文件,其中一些我们可能想要处理,而另一些我们想不理会

假设我们在目录中有两个文件:*“picture.jpg”“image”。当然,我们不想在第一个文件中添加第二个“.jpg”*扩展名。

我们将使用find命令选择正确的文件:

$ find . -not -name "*.*"
./image

然后,我们可以使用*-exec参数和mv*命令重命名返回的文件:

$ find . -not -name "*.*" -exec mv {} {}.jpg \;

或者,我们可以使用一个简单的while循环:

$ find . -not -name "*.*" | while read FILE; do mv "$FILE" "$FILE".jpg; done

4. 按文件类型区分

我们的场景可能会变得更复杂。**我们可能会遇到没有任何扩展名且不是 JPEG 的文件。**请注意,Linux 中的目录也是文件,我们可以拥有要处理的嵌套目录。因此,我们需要进入目录但不要更改它们的名称。

假设我们需要处理五个文件:“picture.jpg”“image”“readme”“nested_directory”,以及在该目录中的*“another_image”。我们只想重命名“image”“another_image”*文件,因为其余文件已经有扩展名,或者不是真正的 JPEG 图像。

幸运的是,find命令也会列出嵌套文件。如果我们想过滤掉目录,我们需要使用–type*参数*:

$ find . -type f -not -name "*.*"
./image
./readme
./nested_directory/another_image

要检查文件的实际类型,我们将使用file命令

$ echo "test" > readme
$ file --mime-type -b readme
text/plain
$ file --mime-type -b image
image/jpeg
$ file --mime-type -b nested
inode/directory

最后,我们将使用带有条件语句的while循环来遍历文件:

find . -type f -not -name "*.*" | while read FILE; do if [ $(file --mime-type -b "$FILE") == "image/jpeg" ]; then mv "$FILE" "$FILE".jpg; fi; done;

我们也可以使用find命令的*-exec参数,但是,我们需要使用bashsh* 命令执行我们的条件语句:

find . -type f -not -name "*.*" -exec bash -c 'if [ $(file --mime-type -b {}) == "image/jpeg" ]; then mv {} {}.jpg; fi;' \;

如果我们想执行一次试运行以确保我们的命令将按照我们的意图执行,我们可以简单地将mv命令替换为echo命令来打印新旧文件名。