查找文件,使用“uuidgen”重命名它们并添加扩展名

Joh*_*shi 4 find rename files

我在某个文件夹中有一个没有扩展名的文件列表。我想重命名它们并添加扩展名。名称应为 UUID。我知道如何找到它们,还有用于生成 UUID 的实用程序“uuidgen”,剩下的我该怎么做?

find . -type f -name 'file*' # ??? -exec .... ???
Run Code Online (Sandbox Code Playgroud)

Joh*_*024 7

尝试:

find . -type f -name 'file*' -execdir sh -c 'mv "$1" "$(uuidgen).ext"' Renamer {} \;
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • find . -type f -name 'file*' -execdir ... \;

    这部分您似乎很熟悉:它查找名称与 glob 匹配的文件file*并对其运行命令...,在我们的例子中,...它被替换为:

  • sh -c 'mv "$1" "$(uuidgen).ext"' Renamer {}

    这将启动一个 shell,运行一个 mv 命令,并使文件名可用为$1. (Renamer是 shell 分配给的任意字符串,$0如果它生成错误消息,shell 将使用该字符串。)该find命令替换{}为它找到的文件的名称,这就是 shell 分配给的内容$1。让我们看看shell命令:

  • mv "$1" "$(uuidgen).ext"

    这会将文件从 重命名$1为由uuidgen.

    因为文件名可能包含空格或其他困难的字符,所以我们$1用双引号括起来以防止名称被分词或 shell 扩展。

我们使用-execdir而不是-exec出于两个原因:

  1. 它使mv命令更容易:不需要额外的代码来确保重命名的文件保留在同一目录中。

  2. -execdir更安全:如果一个目录被重命名,而find命令正在运行,-exec而不是-execdir,可能会失败得很惨。

为什么要启动一个新的shell?

尝试使用以下内容可能很诱人:

find . -type f -name 'file*' -execdir mv {} "$(uuidgen).ext" \; # Don't do this
Run Code Online (Sandbox Code Playgroud)

这里的问题是uuidgen只会运行一次。shell甚至会uuidgen 启动find命令之前运行。因此,所有mv命令都将具有相同的目标文件名。我们希望uuidgen每个找到的文件运行一次find。这就是为什么我们需要运行mvuuidgensh命令。

更高效的版本

以上为找到的每个文件启动一个新的shell。相比之下,以下方法可以在每个 shell 进程启动时处理数千个文件:

find . -type f -name 'fi*' -execdir sh -c 'for f; do mv "$f" "$(uuidgen).ext"; done' Renamer {} +
Run Code Online (Sandbox Code Playgroud)