在Linux上,如何将所有文件夹和文件重命名为小写?

您所在的位置:网站首页 文件名大写改小写 在Linux上,如何将所有文件夹和文件重命名为小写?

在Linux上,如何将所有文件夹和文件重命名为小写?

2024-06-06 15:10| 来源: 网络整理| 查看: 265

我必须递归地重命名一个完整的文件夹树,这样就不会有大写字母出现在任何地方(它是C++源代码,但这不重要)。忽略cvs和svn控制文件/文件夹的奖励积分。首选的方法是shell脚本,因为shell应该在任何Linux设备上都可用。

有一些关于文件重命名详细信息的有效参数。

我认为具有相同小写名称的文件应该被覆盖,这是用户的问题。当在一个案例中签出时,忽略文件系统也会用后者覆盖第一个案例。

我会考虑a-z字符并将其转换为a-z,其他一切都只是为了解决问题(至少是源代码)。

在Linux系统上运行构建需要这个脚本,所以我认为应该忽略对cvs或svn控制文件的更改。毕竟,这只是一个临时结账。也许"出口"更合适。

我还是很喜欢小一点的

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

在不区分大小写的文件系统(如OS X的HFS+)上,您需要添加-f标志

1rename -f 'y/A-Z/a-z/' * 相关讨论 + 1。重命名的手册页中给出了这个确切的示例。 linux.icedog.net/rename.php:The renaming utility that comes by default with Ubuntu is a Perl program sometimes called prename 谢谢,我是这样使用的$find xargs rename'y/a-z/a-z/'。* 隐马尔可夫模型。。。我得到"'./abc.txt'未重命名'。/abc.txt"已经存在",即使它不存在。 如果在那个文件夹中有太多的东西(Rename无法处理超过给定数量的元素(我有大约99k个文件),给你消息"参数列表太长"),你可以使用find . -exec rename 'y/A-Z/a-z/' {} \;。 这假定您具有Perls重命名,但情况并非总是如此。例如,在我的Debian上,重命名完全不同 在arch上,该程序称为perl-rename(由同名包提供) @用户456584您使用的是不区分大小写的文件系统,因此abc.txt和abc.txt有一个相同的文件(也就是说,ntfs或vfat)。使用-f标志 这并不能回答给定的问题,因为"重命名"不是递归的。 @循环代谢只是不断增加/降低水平,直到完成;) @Krzyk在我的Debian Jessie上工作。 Y是音译?我在Rename的手册页(Ubuntu 16.10或带有bash版本3.2.57的OSX)中找不到任何关于"y"的内容,但在sed下找到了这个?manpages.ubuntu.com/manpages/precise/en/man1/sed.1.html页 在OSX上,确保您有重命名。brew install rename 最重要的是:与其他答案不同,我们实际上可以记住这一点! rename -c *或rename -cf *较短。 在OSX上,我得到了rename: command not found。

使用"rename"命令的简明版本。

1find my_root_dir -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

这样可以避免在文件之前重命名目录,并尝试将文件移动到不存在的目录(例如,"A/A"到"A/A"中)时出现问题。

或者,不使用"rename"的更详细的版本。

12345678for SRC in `find my_root_dir -depth` do     DST=`dirname"${SRC}"`/`basename"${SRC}" | tr '[A-Z]' '[a-z]'`     if ["${SRC}" !="${DST}" ]     then         [ ! -e"${DST}" ] && mv -T"${SRC}""${DST}" || echo"${SRC} was not renamed"     fi done

P.S.

后者允许更灵活地使用移动命令(如"svn mv")。

相关讨论 使用重命名可以这样做,也可以重命名为"y/a-z/a-z/"。* 注意,两个版本都不能在不区分大小写的文件系统上工作。在我的例子中,我用(mv"${SRC}""${DST}.renametmp" && mv"${DST}.renametmp""${DST}") || echo"${SRC} was not renamed"替换了then封闭线。 第二种方法对于包含空格的文件(context:linux、bash)不适用。 使用最新版本的rename,不需要regex。全部命令变为find my_root_dir -depth -exec rename -c {} \;。如果您在不区分大小写的文件系统(如mac)上,请添加-f以重命名 第二个在Solaris上为我工作,从mv命令中删除-T。 使用find ... | while read -r SRC代替for循环,修复了我的空白问题。(MAC操作系统) +第二个选项为1。第一个似乎不适合我。 如果您在Git repo中使用它,请确保不要重命名您的.git文件夹中的任何内容。 第一个在Ubuntu 12.04 LTS上为我工作,谢谢两个选项! 我必须添加一个-f才能使重命名生效。我一直收到警告说文件已经存在。 1。不会和现代版本的rename一起工作… 确保你真的有了rename…对于OSX,brew install rename。 查找我的_root_dir-depth-exec rename's/(.*)/([^/]*)/$1/l$2/';此代码有效,但我希望它的大小写颠倒为大写,我该怎么做? 第一个命令说"重命名:参数不足"

1for f in `find`; do mv -v"$f""`echo $f | tr '[A-Z]' '[a-z]'`"; done 相关讨论 请在运行脚本之前执行"mkdir-p a/b/c"。 "find"应替换为用于获取要重命名的文件列表的任何命令;例如,"ls*.c,cpp,h"。 在OS X中工作:) for f in *.txt; do mv -v $f echo$f_tr[:upper:][:lower:]; done与debian上的空格一起使用。 不适用于OSX,只打印find的使用信息。find .似乎可以解决这个问题。 我添加了引号,所以它与空格一起使用 唯一对CentOS有效的解决方案。 所有评论的"合并"版本(答案不能再编辑):for f in `find .`; do mv -v"$f""`echo $f | tr '[A-Z]' '[a-z]'`"; done。 @罗马里克德里根-我和你的版本(在MacOS上)一起去了,而且效果很好。 我的输出是lubuntu16.4上的'[A-Z] [error opening dir]'$' ''[a-z] [error opening dir]'$'

''0 directories, 0 files'

。 这是唯一一个在Fedora工作的 有人能向我解释一下为什么这一点首先有效吗?如果找到./foo和./foo/bar,则先将./foo重命名为./foo,然后再找不到./foo/bar。在下面输入我自己的答案可以解决这个问题。

如果你不需要关心效率的话,只需简单地尝试跟随。

12zip -r foo.zip foo/* unzip -LL foo.zip 相关讨论 哇,这是一个相当低效的方法。 假设当您发现自己需要重命名目录中的文件时,计算效率通常不是一个问题…我认为这可能是这个线程上最具创造性的简单解决方案。事实上,这些琐碎的事情不应该像公认的答案所表明的那样复杂,而且这种解决方法与我想投资于这样一个操作的想法的数量成比例。+ 1000 @彼得,更重要的是,它起作用了!我尝试使用其他更复杂的答案,不管出于什么原因,这些答案超出了我调试的意愿,它们都无法正常工作。这个简单的很有魅力! 这真是太搞笑了——我只是试了一下,结果创造了奇迹。绝对比写剧本简单。 你可以用-0开关(即"零",无压缩)来加快速度,zip -0 -r foo.zip foo/。 非常巧妙!!我考虑过逐步更改文件夹名称(先更改顶级文件夹,再更改内部文件夹,然后重新扫描所有文件夹)等等。但这很管用!谢谢!btw unrar x -cl"file.rar""somefolder/"号 这不会删除任何具有大写字符的文件,在我的情况下,这实际上更有效。但是,您可以删除这两个操作之间的目录,以确保结果只包含具有小写名称的文件。 我不得不在不同的目录结构中更改超过50000个文件名。最初被接受的答案在2分钟内只完成了10%的工作,而使用-0压缩,这几乎是瞬间完成的! 这不仅仅是效率低下。如果没有足够的可用空间用于临时存档,这是完全不可能的。 其他的解决方案在OSX上都没有很快对我起作用,这是一种享受。谢谢。

上面的大多数答案都是危险的,因为它们不处理包含奇数字符的名称。对于这种情况,最安全的选择是使用find的-print0选项,它将使用ascii nul而不是终止文件名。在这里,我提交这个脚本,它只更改文件,而不更改目录名,以免混淆find。

123find .  -type f -print0 | xargs -0n 1 bash -c \ 's=$(dirname"$0")/$(basename"$0"); d=$(dirname"$0")/$(basename"$0"|tr"[A-Z]""[a-z]"); mv -f"$s""$d"'

我测试过它,它与包含空格、各种引号等的文件名一起工作。这很重要,因为如果您以根目录运行树上的其他脚本之一,其中包括由以下对象创建的文件:

1touch \;\ echo\ hacker::0:0:hacker:\$\'\057\'root:\$\'\057\'bin\$\'\057\'bash

…好吧,猜猜看……

相关讨论 使用rename而不是mv会更简单。

如果您已经有或设置了RENAME命令(例如,通过在Mac中安装BREW),则可以使用此命令:

1rename --lower-case --force somedir/* 相关讨论 …如果先设置重命名,例如通过brew install rename。 重命名"y/a-z/a-z/"* --lower-case号?至少在ArchLinux中,情况并非如此。 rename不是bash内置的。它是一个外部实用程序,语法将根据您安装的版本而有所不同。这个答案不足以作为所谓的"适用于所有基于Unix的操作系统"的可移植解决方案。 man7.org/linux/man-pages/man1/rename.1.html版本 刚刚检查过,最新Fedora(28)中包含的rename命令,通过util-linux-2.31包,没有--lower-case选项。

伙计,你们喜欢把事情搞得过于复杂……

重命名"y/a-z/a-z/"*

相关讨论 这不起作用,它说具有较低名称的文件已经存在。 @Kirhgoff我已经看到了使用NFS挂载的情况——请按照这里的说明操作。 在我看来,这应该是有标记的答案。 你猜怎么着,6年前也有同样的想法…

这适用于CentOS/RedHat或其他发行版,不使用renamePerl脚本:

1for i in $( ls | grep [A-Z] ); do mv -i"$i""`echo $i | tr 'A-Z' 'a-z'`"; done

来源:https://linuxconfig.org/rename-all-files-from-uppercase-to-lowercase-characters

(在某些发行版中,默认的rename命令来自于util linux,这是一个不同的、不兼容的工具)

相关讨论 我更正了它,所以它也适用于空格 这只在一个目录上工作,而不是递归地

使用Larry Wall的文件名修复程序

12345678$op = shift or die $help; chomp(@ARGV = ) unless @ARGV; for (@ARGV) {     $was = $_;     eval $op;     die $@ if $@;     rename($was,$_) unless $was eq $_; }

这很简单

1find | fix 'tr/A-Z/a-z/'

(fix当然是上面的脚本)

原始问题要求忽略svn和cvs目录,这可以通过向find命令添加-prune来完成。例如,忽略cvs:

1find . -name CVS -prune -o -exec mv '{}' `echo {} | tr '[A-Z]' '[a-z]'` \; -print

[编辑]我尝试了这个方法,但由于我不太明白的原因,在搜索结果中嵌入小写翻译不起作用。因此,将此修改为:

123456$> cat > tolower #!/bin/bash mv $1 `echo $1 | tr '[:upper:]' '[:lower:]'` ^D $> chmod u+x tolower $> find . -name CVS -prune -o -exec tolower '{}'  \;

伊恩

下面是我的次优解决方案,使用bash shell脚本:

123456789101112131415161718#!/bin/bash # first, rename all folders for f in `find . -depth ! -name CVS -type d`; do    g=`dirname"$f"`/`basename"$f" | tr '[A-Z]' '[a-z]'`    if ["xxx$f" !="xxx$g" ]; then       echo"Renaming folder $f"       mv -f"$f""$g"    fi done # now, rename all files for f in `find . ! -type d`; do    g=`dirname"$f"`/`basename"$f" | tr '[A-Z]' '[a-z]'`    if ["xxx$f" !="xxx$g" ]; then       echo"Renaming file $f"       mv -f"$f""$g"    fi done

编辑:我根据目前的建议做了一些修改。现在文件夹都被正确重命名了,当权限不匹配时,mv不会询问问题,也不会重命名cvs文件夹(很遗憾,该文件夹中的cvs控制文件仍然被重命名)。

编辑:因为"find-depth"和"find sort-r"都以可用的顺序返回文件夹列表进行重命名,所以我更喜欢使用"-depth"搜索文件夹。

相关讨论 你的第一个发现不起作用。尝试"mkdir-p a/b/c",然后运行脚本。

这是一个小的shell脚本,执行您的请求:

1234567root_directory="${1?-please specify parent directory}" do_it () {     awk '{ lc= tolower($0); if (lc != $0) print"mv ""  $0"" "" lc""" }' | sh } # first the folders find"$root_directory" -depth -type d | do_it find"$root_directory" ! -type d | do_it

注意第一个查找中的深度操作。

相关讨论 唯一能在Mac上运行的东西。谢谢堆!

使用MACOS,

安装rename包,

1brew install rename

使用,

1find . -iname"*.py" -type f | xargs -I% rename -c -f "%"

此命令查找扩展名为*.py的所有文件,并将文件名转换为小写。

1`f` - forces a rename

例如,

1234567$ find . -iname"*.py" -type f ./sample/Sample_File.py ./sample_file.py $ find . -iname"*.py" -type f | xargs -I% rename -c -f "%" $ find . -iname"*.py" -type f ./sample/sample_file.py ./sample_file.py 相关讨论 你为什么在这里使用-I选项来选择xargs? - I标志不是强制性的。当我们使用xargs执行多个命令时使用。下面是一个使用多个命令的示例,使用xargscat foo.txt | xargs -I % sh -c 'echo %; mkdir %',您可以在没有-I的情况下运行,如find . -iname"*.py" -type f | xargs -I% rename -c -f "%"。

以前发布的将完全不受限制地工作,或者对简单情况进行一些调整,但是在运行批重命名之前,您可能需要考虑一些情况:

如果在路径层次结构中有两个或多个相同级别的名称(仅因情况而不同),如ABCdef、ABCdef和ABCdef,会发生什么情况?重命名脚本应该中止还是只发出警告并继续?

如何定义非US-ASCII名称的小写?如果可能存在这样的名称,应该首先执行一次检查和排除传递吗?

如果在cvs或svn工作副本上运行重命名操作,则如果更改文件名或目录名的大小写,可能会损坏工作副本。脚本是否还应查找和调整内部管理文件,如.svn/entries或cvs/entries?

不可移植,仅限zsh,但相当简洁。

首先,确保加载了zmv。

1autoload -U zmv

另外,确保extendedglob打开:

1setopt extendedglob

然后使用:

1zmv '(**/)(*)~CVS~**/CVS' '${1}${(L)2}'

以递归方式小写文件和目录,其中名称不是cvs。

在OSX中,mv-f显示"相同文件"错误,所以我重命名了两次。

1for i in `find . -name"*" -type f |grep -e"[A-Z]"`; do j=`echo $i | tr '[A-Z]' '[a-z]' | sed s/\-1$//`; mv $i $i-1; mv $i-1 $j; done 1for f in `find -depth`; do mv ${f} ${f,,} ; done

find -depth打印每个文件和目录,目录的内容打印在目录本身之前。${f,,}lower会显示文件名。

相关讨论 这不起作用:它在对内容进行操作之前重命名一个目录,这样以后对内容的尝试就失败了。 添加-depth可以修复这个问题!这是一个非常快速的解决方案,但当然,如果不使用-print0选项来查找,它不是最可靠的 @不,不是。它将尝试将/foo/bar重命名为/foo/bar,但是/foo当时还不存在。

在这种情况下,我会使用python,以避免乐观地假设没有空格或斜线的路径。我还发现,与rename相比,python2的安装位置更多。

123456789101112131415161718192021#!/usr/bin/env python2 import sys, os def rename_dir(directory):   print('DEBUG: rename('+directory+')')   # rename current directory if needed   os.rename(directory, directory.lower())   directory = directory.lower()   # rename children   for fn in os.listdir(directory):     path = os.path.join(directory, fn)     os.rename(path, path.lower())     path = path.lower()     # rename children within, if this child is a directory     if os.path.isdir(path):         rename_dir(path) # run program, using the first argument passed to this python script as the name of the folder rename_dir(sys.argv[1]) 相关讨论 谈一谈让事情复杂化…只要做…重命名"y/a-z/a-z/"* @斯蒂芬,假设你有安装重命名的管理员权限。我经常需要在我没有能力安装其他软件的系统上咀嚼数据。在最近的Ubuntus中,只有在存在perl的情况下才安装它。

1234( find YOURDIR -type d | sort -r;   find yourdir -type f ) | grep -v /CVS | grep -v /SVN | while read f; do mv -v $f `echo $f | tr '[A-Z]' '[a-z]'`; done

首先从下到上重命名目录sort-r(其中-depth不可用),然后重命名文件。然后grep-v/cvs而不是find…-修剪,因为它更简单。对于大目录,对于中的f…会溢出一些外壳缓冲区。使用查找…|同时阅读以避免这种情况。

是的,这将删除不同的文件,只有在案件…

相关讨论 第一:find YOURDIR -type d | sort -r太麻烦了。你要的是find YOURDIR -depth -type d。其次,find -type f必须在目录重命名后运行。

slugify重命名(regex)

不完全是OP要求的,但我希望在这一页上找到:

用于重命名文件的"slugify"版本,因此它们与URL类似(即仅包括字母数字、点和破折号):

1rename"s/[^a-zA-Z0-9\.]+/-/g" filename 相关讨论 "不完全是"?这根本不是OP要求的

1find . -depth -name '*[A-Z]*'|sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'|sh

我没有尝试过这里提到的更复杂的脚本,但是在我的滑膜NAS上,没有一个命令行版本对我有用。rename不可用,find的许多变体都失败了,因为它似乎坚持已重命名路径的旧名称(例如,如果它发现./FOO后接./FOO/BAR,则将./FOO重命名为./FOO仍将继续列出./FOO/BAR,即使该路径不再有效)。上面的命令对我没有任何影响。

下面是对命令每个部分的解释:

1find . -depth -name '*[A-Z]*'

这将使用深度优先搜索(例如,它将在./FOO之前列出./FOO/BAR)来查找当前目录中的任何文件(将.更改为要处理的任何目录),但仅限于包含大写字符的文件。-name过滤器仅适用于基本文件名,而不适用于完整路径。因此,这将列出./FOO/BAR,而不是./FOO/BAR。这没关系,因为我们不想重命名./FOO/BAR。不过,我们想重新命名./FOO,但该名称在后面列出(这就是-depth很重要的原因)。

这个命令本身对于首先查找要重命名的文件特别有用。在完成重命名命令后使用此命令搜索由于文件名冲突或错误而尚未被替换的文件。

1sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'

本部分读取find输出的文件,并使用正则表达式将其格式化为mv命令。-n选项阻止sed打印输入,搜索和替换regex中的p命令输出替换的文本。

regex本身包含两个捕获:直到最后一个(文件的目录)的部分和文件名本身。目录保持不变,但文件名转换为小写。因此,如果find输出./FOO/BAR,它将成为mv -n -v -T ./FOO/BAR ./FOO/bar。mv的-n选项确保不会覆盖现有的小写文件。-v选项使mv输出它所做的每一个更改(或不做的每一个更改-如果./FOO/BAR已经存在,它输出类似./FOO/BAR -> ./FOO/BAR的内容,注意到没有做任何更改)。-T在这里非常重要,它将目标文件视为一个目录。这将确保如果该目录恰好存在,则不会将./FOO/BAR移动到./FOO/BAR中。

将它与find一起使用,生成将要执行的命令列表(方便验证将要执行的操作而不实际执行)

1sh

这是不言自明的。它将所有生成的mv命令路由到shell解释器。你可以用bash或者任何你喜欢的外壳来代替它。

如果使用arch linux,则可以从AUR安装rename包,该包提供renamexm命令作为/usr/bin/renamexm可执行文件,并随附其手册页。

它是快速重命名文件和目录的强大工具。

转换为小写 1rename -l Developers.mp3 # or --lowcase

转换为大写

1rename -u developers.mp3 # or --upcase, long option

其他选项

1234567891011-R --recursive # directory and its children -t --test # dry run, output but don't rename -o --owner # change file owner as well to user specified -v --verbose # output what file is renamed and its new name -s/str/str2 # substite string on pattern --yes # Confirm all actions

如果需要,可以从这里获取示例developers.mp3文件;)

相关讨论 MacOS上从brew重命名时,-l绑定到创建一个符号链接,-c转换为小写,所以要小心。

没人建议打字?

12345typeset -l new        # always lowercase find $topPoint |      # not using xargs to make this more readable   while read old   do mv"$old""$new" # quotes for those annoying embedded spaces   done

在类似Git-Bash的Windows仿真中,这可能会失败,因为Windows在引擎盖下不区分大小写。对于这些,首先添加一个步骤,将mv作为文件名,比如"$old.tmp",然后添加到$new。

冗长但"工作时不会有意外,也不会安装"

此脚本处理带有空格、引号、其他不寻常字符和Unicode的文件名,适用于不区分大小写的文件系统和大多数安装了bash和awk的Unix-Y环境(即几乎所有)。它还报告冲突(如果有)(将文件名保留为大写),当然,重命名两个文件和目录并以递归方式工作。最后,它具有很强的适应性:您可以调整find命令以针对您希望的文件/目录,还可以调整awk以执行其他名称操作。注意,"handles unicode"的意思是它确实会转换它们的情况(不要像使用tr的答案那样忽略它们)。

123456789101112131415# adapt the following command _IF_ you want to deal with specific files/dirs find . -depth -mindepth 1 -exec bash -c '   for file do     # adapt the awk command if you wish to rename to something other than lowercase     newname=$(dirname"$file")/$(basename"$file" | awk"{print tolower(\$0)}")     if ["$file" !="$newname" ] ; then         # the extra step with the temp filename is for case-insensitive filesystems         if [ ! -e"$newname" ] && [ ! -e"$newname.lcrnm.tmp" ] ; then            mv -T"$file""$newname.lcrnm.tmp" && mv -T"$newname.lcrnm.tmp""$newname"         else            echo"ERROR: Name already exists: $newname"         fi     fi       done ' sh {} +

工具书类

我的剧本基于这些优秀的答案:

https://unix.stackexchange.com/questions/9496/looping-through-files-with-spaces-in-the-names

如何在bash中将字符串转换为小写?

这也适用于MacOS:

1ruby -e"Dir['*'].each { |p| File.rename(p, p.downcase) }" 相关讨论 这特别好,因为Ruby附带MacOS。

我需要在Windows7上的cygwin设置上执行此操作,并发现我在上面给出的建议中出现语法错误(尽管我可能错过了一个工作选项),但是这个直接从ubutu论坛获得的解决方案在can中成功了:-)

1ls | while read upName; do loName=`echo"${upName}" | tr '[:upper:]' '[:lower:]'`; mv"$upName""$loName"; done

(注意,我以前用下划线替换过空格

1for f in *\ *; do mv"$f""${f// /_}"; done


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3