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

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

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

我发现一些脚本可以将其转换为小写,但我不知道如何更改它们,因此它会以相反的方式进行(从小到大)。

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

rename 'y/A-Z/a-z/' *

来自于man rename

答案1

请注意,您正在使用Perl 脚本称为rename由 Debian 及其衍生产品(Ubuntu、Mint 等)分发。其他 Linux 发行版提供了一个完全不同且不太有用的命令,称为rename

y/A-Z/a-z/将范围Athrough中的每个字符转换Z为范围athrough中的相应字符z,即 ASCII 大写字母转换为相应的小写字母。要执行相反的转换,请使用y/a-z/A-Z/.编写相同命令的另一种方法是rename '$_ = uc($_)' *uc佩尔Case 函数,该rename命令根据对$_变量所做的转换来重命名文件。

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

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

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

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

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

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

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

zmv -w '**/*' '$1$2:u'

解释:

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

作为额外的好处,这会尊重环境区域设置。

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

答案2

我想引导任何仍然与此答案相关联的人优秀的答案Guiles Quernot 给出了这个不需要的问题find

结果命令将是:

shopt -s globstar
rename -n 'y/a-z/A-Z/' **

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

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

答案3

从 Gilles 的帖子中被盗(稍作修改)这里

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

答案4

移动到您要重命名文件的目录后尝试此操作:

for word in `ls -ltr |tail -n +2 |awk '{print $9}'`
do
  a=$(echo $word | tr '[a-z]' '[A-Z]')
  mv $word $a
  echo "Done Successfully"
done

相关内容