如何重命名的所有文件夹和文件为小写在Linux上?(How to rename all folder

2019-07-21 02:41发布

我有递归重命名一个完整的文件夹树,以便没有大写字母出现的任何地方(这是C ++中源代码,但是这不应该的问题)。 加分忽略CVS和SVN控制的文件/文件夹。 最好的办法是一个shell脚本,因为壳应在任何Linux中可用。

有关于文件重命名的一些细节上的有效参数。

  1. 我想用相同的小写字母名称的文件应该被覆盖,这是用户的问题。 当的情况下,忽略文件系统上确认将会覆盖第一个与后者了。

  2. 我会考虑AZ字符,并将其转化为AZ,一切只是呼吁的问题(至少与源代码)。

  3. 将需要的脚本在Linux系统上运行构建,所以我觉得应该省略CVS或SVN控制文件的更改。 毕竟,这只是一个临时结算。 也许一个“出口”是比较合适的。

Answer 1:

使用简明版"rename"命令。

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

这避免了与之前的文件被重命名,并试图将文件移动到不存在的目录(如目录的问题"A/A""a/a" )。

或者,一个更详细的版本,而不使用"rename"

for 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

PS

后者允许与移动命令(例如更多的灵活性"svn mv" )。



Answer 2:

小我还是挺喜欢

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

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

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


Answer 3:

for f in `find`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done


Answer 4:

只需简单地尝试,如果你不需要关心效率以下。

zip -r foo.zip foo/*
unzip -LL foo.zip


Answer 5:

大部分的答案以上是危险的,因为他们不包含奇怪的字符名称处理。 您最安全的这种事情的办法是使用发现的-print0选项,它将终止与ASCII NUL,而不是\ n文件名。 在这里,我提出以下脚本,它只是改变文件,而不是目录名,以免混淆发现。

find .  -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"'

我测试了它,并将它与含有空格,各种报价,文件名等。这一点很重要,因为如果你运行,作为根,在树与其他脚本的一个包括由创建该文件的工作原理:

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

...好你猜怎么着?



Answer 6:

这工作如果你已经拥有或建立重命名命令(例如,通过BREW安装在Mac):

rename --lower-case --force somedir/*


Answer 7:

男子你们想在复杂的事情..

重命名 'Y / AZ / AZ /' *



Answer 8:

这个工程在CentOS /红帽或其他分派,而不rename Perl脚本:

for 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的,这是一个不同的,不兼容的工具)



Answer 9:

使用Larry Wall的文件名定影液

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

它的那样简单

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

(其中修复当然上面的脚本)



Answer 10:

原来的问题问忽略SVN和CVS目录,这可以通过添加-prune到find命令来完成。 如忽略CVS:

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

[编辑]我想这一点,并嵌入在里面找小写翻译没有原因,我并不真正了解工作。 因此,修订本于:

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

伊恩



Answer 11:

这里是我的次优解决方案,使用一个bash shell脚本:

#!/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控制文件仍改名,可惜)。

编辑:既然“找-depth”和“找|排序-r”无论是在一个可用的顺序重新命名返回文件夹列表中,我用者优先“-depth”搜索文件夹。



Answer 12:

这是一个小的shell脚本,做你的要求是什么:

root_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

请注意,在第一个找到-depth行动。



Answer 13:

先前公布将很好地工作开箱即用或简单的情况下做一些调整,但也有你可能要考虑运行的批量重命名之前的一些情况:

  1. 如果你有在路径分级仅由大小写不同的同级别两个或两个以上的名字,比如应该发生什么ABCdefabcDEFaBcDeF ? 如果重命名脚本中止或只是警告并继续吗?

  2. 你如何对非US-ASCII名称来定义小写? 如果这样的名字可能存在,应该检查并排除首先进行通?

  3. 如果你正在运行的CVS或SVN工作副本重命名操作,你可能会破坏工作副本,如果你改变文件或目录名的情况。 如果该脚本还发现,调整内部管理文件,如的.svn /项或CVS /项?



Answer 14:

和MacOS,

安装rename包,

brew install rename

使用,

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

此命令查找所有与文件*.py扩展名和文件名转换为小写。

`f` - forces a rename

例如,

$ 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


Answer 15:

不便携,仅岩组,但相当简洁。

首先,确保zmv被加载。

autoload -U zmv

此外,还要确保extendedglob是:

setopt extendedglob

然后使用:

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

递归小写的文件和目录,其中名称不CVS。



Answer 16:

在OSX,MV -f显示“相同的文件”的错误,所以我改名的两倍。

for 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


Answer 17:

我想在这种情况下达到蟒蛇,以避免乐观假设没有空格或斜线的路径。 我还发现, python2往往被安装在比更多的地方rename

#!/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])


Answer 18:

for f in `find -depth`; do mv ${f} ${f,,} ; done

find -depth打印每个文件和目录,以目录本身之前打印目录的内容。 ${f,,}小写字母的文件名。



Answer 19:

( 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

首先重命名的目录下向上排序-R(其中-depth不可用),然后将文件。 随后的grep -v / CVS,而不是找...-修剪 ,因为它更简单。 对于大型目录, 对于f在...可能会溢出一些贝壳缓冲区。 使用find ... | 而读避免。

是的,这会揍只在不同的情况下,文件...



Answer 20:

Slugify重命名(正则表达式)

不正是OP问,但我希望能找到这个页面上:

A“slugify”版本,所以他们与URL类似重命名文件
(即只包含字母数字,点和短划线):

rename "s/[^a-zA-Z0-9\.]+/-/g" filename


Answer 21:

我需要做的这对一个cygwin安装在Windows 7上,发现我的语法错误,从上面,我试过的建议(虽然我可能已经错过了一个工作的选项),但是从直该解决方案从ubutu论坛摸索出罐:-)

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

(注:我一直在使用之前替换用下划线空白

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


Answer 22:

如果您使用的Arch Linux ,你可以安装rename的包AUR提供renamexm命令/usr/bin/renamexm可执行文件和它的手动与它一起页面。

这实在是功能强大的工具来快速重命名文件和目录。

转换为小写

rename -l Developers.mp3 # or --lowcase

转换为大写

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

其他选项

-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文件在这里 ,如果需要的话)



Answer 23:

没有人暗示排版?

typeset -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

在Windows仿真像git的庆典,这可能会失败,因为Windows是不区分引擎盖下的敏感。 针对这一情况,增加一个步骤,其MV的文件到另一个名头,如“$ old.tmp”,然后到$新。



Answer 24:

但冗长“工程与没有意外和不安装”

该脚本处理的文件名有空格,引号等特殊字符和Unicode,适用于区分大小写的文件系统,并且有bash和AWK安装(即几乎所有的) 大多数的Unix-Y环境 。 它还报告冲突,如果任何(留下大写的文件名),当然重命名这两个文件和目录和工作递归。 最后,它的高度适应性:你可以调整find命令到目标文件/迪尔斯你愿意,你可以调整AWK做其他名称的操作。 请注意,“处理Unicode”我的意思是,它的确会转换自己的情况(不能忽视他们喜欢使用的答案tr )。

# 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为小写转换?



Answer 25:

这很好地工作在MacOS太:

ruby -e "Dir['*'].each { |p| File.rename(p, p.downcase) }"


Answer 26:

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

我还没有尝试过这里提到的更复杂的脚本,但没有一个单一的命令行版本的工作对我来说我的Synology NAS。 rename不可用,和许多的变化, find失败,因为它似乎粘在已经更名为路径的旧的名称(例如,如果发现./FOO其次./FOO/BAR ,重命名./FOO./foo还是会继续列出./FOO/BAR即使该路径不再有效)。 上面的命令工作对我来说没有任何问题。

接下来是命令的各部分的解释:


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

这将会找到当前目录下的文件(其他城市.你要处理的任何目录),使用深度优先搜索(例如,它会列出./foo/bar./foo ),但仅限于文件包含大写字符。 该-name过滤仅适用于基本文件名,而不是完整路径。 因此,这将列出./FOO/BAR但不./FOO/bar 。 这是确定的,因为我们不希望重命名./FOO/bar 。 我们要重命名./FOO虽然,但,一个是上市以后(这就是为什么-depth很重要)。

这COMAND本身是特别有用的发现,你要摆在首位,以重命名文件。 使用这个完整的重命名命令后,以搜索还没有被替换,因为文件名冲突或错误的文件。


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

这部分内容由输出的文件find并格式化他们在mv使用正则表达式的命令。 所述-n选项停止sed从打印输入,并且p在搜索和替换命令的正则表达式的输出替换文本。

正则表达式本身由两个捕获的:一部分,直到最后/(这是该文件的目录),文件名本身。 该目录将保持不变,但文件名被转换为小写。 所以,如果find输出./FOO/BAR ,它将成为mv -n -v -T ./FOO/BAR ./FOO/bar 。 该-n的选项mv确保现有的小写的文件不会被覆盖。 该-v选项使得mv输出每一个改变,它使(或不作-如果./FOO/bar已经存在,它输出类似./FOO/BAR -> ./FOO/BAR注意到没有变化已经取得)。 该-T在这里非常重要-它把目标文件的目录。 这将确保./FOO/BAR没有搬进./FOO/bar如果该目录恰好存在。

再加上使用此find产生将要执行的命令列表(方便验证会怎样做没有实际去做)


sh

这不言自明。 它会将所有生成的mv命令,命令解释程序。 你可以将其替换为bash或自己的喜好任意外壳。



文章来源: How to rename all folders and files to lowercase on Linux?