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


11

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

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

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

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

是来自man rename


在不了解重命名命令的情况下,我怀疑如果您尝试一下rename 'y/a-z/A-Z/' *,将会得到想要的东西。仔细在哪里进行测试。
沃里克

它不是递归的(因为最初不是...),但是它可以工作。我不明白为什么我不对自己这么强:),,!
jnhghy-Alexandru Jantea 2014年

我认为,鉴于吉尔(Gilles)回答的质量,如果您优先接受他的回答而不是我的回答,那会很好。它比我的完整得多,并解释了您的选择(及其全部工作原理)。谢谢。
沃里克

Answers:


8

请注意,您使用的是由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' {} +

zsh外壳提供了更方便的重命名功能-比Perl更加隐秘,但更麻烦,而且通常更易于编写。

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

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

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

说明:

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

作为一项额外的奖励,它尊重周围的语言环境设置。

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


5

从Gilles偷走(有少量修改)在这里

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


这不是递归操作。
吉尔(Gilles)'所以

真正。我应该已经正确阅读了这个问题。我没有重命名命令的访问权限,但我相信这将递归起作用find <dir> -exec rename 'y/a-z/A-Z/' {} \;
Warwick

比这复杂一点,因为您要在递归目录的同时重命名目录find
吉尔斯(Gillles)“所以-别再邪恶了”

@吉尔斯-好的。经过一些研究,看来我需要添加-depth选项来查找,以便最后处理目录名。因此find <dir> -depth -exec rename 'y/a-z/A-Z/' {} \;应处理重命名目录的问题。正确?
沃威克

不,那仍然不起作用,因为此时对和的rename更改不存在。foo/barFOO/BARFOO
吉尔(Gilles)'所以

2

我想将仍然与该答案相关联的任何人指向吉莱斯·奎诺特(Guilles Quernot)对这个不需要的问题给出的出色答案find

结果命令将是:

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

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

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


1

find -execdir| 改名

如果不是因为相对路径疯狂,这将是最好的方法,因为它避免了Perl regex fu仅对基名称起作用:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
  find a -depth -execdir rename 's/(.*)/\U$1/' '{}' \;

-execdir首先cd进入目录,然后仅对基本名称执行。

不幸的是,如果您在...中有相对路径,我将无法摆脱这一PATH黑客问题,并且find -execdir拒绝执行任何操作PATHhttps : //askubuntu.com/questions/621132/why-using-the-execdir-action-目录路径不安全/ 1109378#1109378


0

移至要重命名文件的目录后,请尝试以下操作:

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

不要解析ls的输出(为什么在地球上您会ls -l只切除名字以外的列?),并在变量替换处使用双引号。您的代码过于复杂,并且破坏了包含空格和其他特殊字符的文件名。使用find**/递归到子目录中,的输出ls仅用于人类消费。
吉尔(Gilles)'所以
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.