如何使用重命名递归地将所有内容重命名为大写

jnh*_*tea 11 recursive rename files

我想递归地将所有文件和文件夹(子文件夹)重命名为大写。

我找到了一些可以将其转换为小写的脚本,但我不知道如何更改它们,因此它会以相反的方式(从低到高)执行此操作。

我找到并适用于小写的脚本,但我不知道如何修改:

rename 'y/A-Z/a-z/' *
Run Code Online (Sandbox Code Playgroud)

它来自man rename.

Gil*_*il' 12

请注意,您使用的是由 Debian 及其衍生产品(Ubuntu、Mint ……)分发的Perl 脚本rename。其他 Linux 发行版提供了一个完全不同的、而且相当不实用的命令,称为rename.

y/A-Z/a-z/转换范围内的每个字符A通过Z进入该范围中的对应的字符a通过z,即ASCII大写字母到相应的小写字母。要执行相反的转换,请使用y/a-z/A-Z/。写同样的命令是另一种方式rename '$_ = uc($_)' *ucü PPER Ç酶功能,并且rename命令基于对所做的改造重命名文件$_变量。

rename '…' *只重命名当前目录中的文件,因为这是*匹配的。点文件(名称以.)也被跳过。

如果要递归重命名当前目录和子目录中的文件,可以使用该find命令递归遍历当前目录。这里有一个困难:如果您调用rename,这将重命名目录和基本名称部分。如果您rename在递归进入一个目录 ( find -exec rename … {} \;)之前调用它,find会感到困惑,因为它找到了一个目录,但当它尝试下降到该目录时该目录不再存在。您可以通过告诉find在对其执行操作之前遍历目录来解决此问题,但是您最终会尝试重命名foo/barFOO/BAR目录FOO不存在。

避免这种困难的一种简单方法是使重命名命令仅作用于路径的基本名称部分。正则表达式([^/]*\Z)匹配不包含/.

find . -depth -exec rename 's!([^/]*\Z)!uc($1)!e' {} +
Run Code Online (Sandbox Code Playgroud)

外壳zsh提供了更方便的重命名功能——甚至比 Perl 更神秘,但更简洁,而且通常更容易编写。

该函数zmv根据模式重命名文件。运行autoload -U zmv一次以激活它(将此行放在您的.zshrc)。

zmv(要替换的模式)的第一个参数中,您可以使用 zsh 强大的通配符模式。在zmv(替换文本)的第二个参数中,您可以使用其参数扩展功能,包括历史修饰符

zmv -w '**/*' '$1$2:u'
Run Code Online (Sandbox Code Playgroud)

解释:

  • -w — 自动为每个通配符模式分配数字变量
  • **/*- 子目录中的所有文件,递归(**/匹配 0、1 或更多级别的子目录)
  • $1 — 第一个数字变量,这里匹配每个路径的目录部分
  • $2:u— 第二个数字变量,这里匹配每个路径的基本名称部分,使用:u修饰符将值转换为大写

作为一个额外的好处,这尊重环境语言环境设置。

如果您不确定zmv您编写的命令,您可以传递-n选项来打印命令将执行的操作而不更改任何内容。检查输出,如果它符合您的要求,请重新运行命令而不-n实际操作。


小智 6

我想引导那些仍然与这个答案相关的人看到Guiles Quernot 对这个问题给出的优秀答案,这个问题不需要find

结果命令将是:

shopt -s globstar
rename -n 'y/a-z/A-Z/' **
Run Code Online (Sandbox Code Playgroud)

但在运行之前,请阅读链接的答案,了解有关旧 bash 版本的警告。

最后,如果有人想知道该y///命令在perl regex. 这是相关文档的链接。


War*_*ick 5

从吉尔斯那里偷来的(稍作修改)张贴在这里

find <DIR> -depth -type d -exec rename -n 's!/([^/]*/?)$!\U/$1!' {} +