我有一些大写的文件和文件夹,我想重新命名为小写的等价物。 在Linux系统上用bash来做这件事最好的办法是什么?
作为一个例子,我可能会有:
. |-- FOLDER0 | |-- SUBFOLDERA | `-- SUBFOLDERB `-- FOLDER1 `-- AFILE.TXT
我想将其转换为:
. |-- folder0 | |-- subfoldera | `-- subfolderb `-- folder1 `-- afile.txt
我可以写一个深度的第一个recursion的脚本来做到这一点(深度优先,以确保文件和子文件夹被重命名之前,他们的父文件夹),但我想知道是否有更好的办法。 rename可能是有用的,但它似乎不支持recursion。
find . -depth -print0 | xargs -0 rename -n '$_ = lc $_'
一旦确定它正在做你想做的事,就把-n标志拿出来。
这更多的是对这个论坛的工作方式进行评论和观察,但是我觉得这个问题应该比我刚才在rudedog的回答中留下评论的时候要大声一点。 这也是一个意见,更多的人可能有一个类似戴维·迪恩的问题,但不完全相同的问题。
用重命名文件的recursion操作很容易造成巨大的损失。 让我再说一遍,因为这非常重要。 您可以使用重命名文件的recursion操作非常快速地摧毁大量数据。 您可以快速渲染完全无法使用的系统。 您可以非常快速地删除99%的数据。 这样的行动应该非常仔细地进行,并进行大量的思考,备份和testing。
我对这个具体问题的答案非常谨慎,这个问题依赖于几个具体的隐含假设:
做完快捷方式,我感到很舒服。 然而,我试图理解,有些东西是捷径,这样的捷径有什么限制,所以我知道什么时候需要运行正确的程序,或者快一万倍,但是在一些边界情况下快捷失败。
总之 – 上述使用重命名的脚本在90%的情况下是100%合理的。 在100%的案例解决scheme中100%正确实际上有点复杂,需要一些智能来处理命名空间冲突。
但是,正如我之前所说的,对于recursion文件操作要特别小心,特别是如果它们只包含权限或文件名等元数据。 他们快速,难以倒转,无需备份…
下面是一个如何在bash或ksh或其他一些“排版”的现代shell中编写“rename”命令的例子。 我们来调用这个脚本/ tmp / squash
#!/usr/local/bin/pdksh # use some shell that supports typeset such as ksh, pdksh, or bash # call this script from "xargs -0" and feed it with "find -print0" typeset -l targetname || { echo "This shell doesn't support typeset!" >&2 ; exit 1 ; } for file do count="" target="$file" targetpath="${target%/*}/" targetname="${target##*/}" if [[ "$file" == "$targetpath$targetname" ]] || [[ "$file" == . ]] then : else while test -e "$targetpath/$targetname""$count" do count=$((${count:-0}+1)) done echo "renaming $file to $targetpath$targetname$count" >&2 mv -n "$file" "$targetpath$targetname$count" fi done
现在,您可以运行以下两个命令,并将文件全部压扁,并且不会覆盖任何文件。
find /path/to/files -type f -print0 | xargs -0 /tmp/squash find /path/to/files -type d -depth -print0 | xargs -0 /tmp/squash
我正在做的假设,有问题的目录不会有东西放进去,或者在我运行程序时重命名的东西。
我会推迟到其他人的答案,但-type f和-type d作为find的参数将分别返回文件和目录。 如果你想先改变文件,然后改变目录…然后改变文件,然后改变目录。