我在某个文件夹中有一个没有扩展名的文件列表。我想重命名它们并添加扩展名。名称应为 UUID。我知道如何找到它们,还有用于生成 UUID 的实用程序“uuidgen”,剩下的我该怎么做?
find . -type f -name 'file*' # ??? -exec .... ???
Run Code Online (Sandbox Code Playgroud)
尝试:
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
出于两个原因:
它使mv
命令更容易:不需要额外的代码来确保重命名的文件保留在同一目录中。
-execdir
更安全:如果一个目录被重命名,而在find
命令正在运行,-exec
而不是-execdir
,可能会失败得很惨。
尝试使用以下内容可能很诱人:
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
。这就是为什么我们需要运行mv
和uuidgen
下sh
命令。
以上为找到的每个文件启动一个新的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)
归档时间: |
|
查看次数: |
1212 次 |
最近记录: |