在ubuntu / bash下recursion地重命名文件和目录
我想重新命名包含单词“special”的所有文件和目录为“regular”。 它应该保持区分大小写,以便“特殊”不会变成“正常”。
我怎样才能在bash中recursion地做到这一点?
尝试这样做(需要bash --version
> = 4):
shopt -s globstar rename -n 's/special/regular/' **
当您的testing正常时,请移除-n
开关
还有其他同名的工具可以或不可以这样做,所以要小心。
如果您运行以下命令( GNU
)
$ file "$(readlink -f "$(type -p rename)")"
你有一个像这样的结果
.../rename: Perl script, ASCII text executable
不包含:
ELF
那么这似乎是正确的工具=)
如果没有,在Debian
和衍生工具(如Ubuntu
)上将其设为默认(通常已经是这种情况):
$ sudo update-alternatives --set rename /path/to/rename
(replace/path/to/rename
您的perl's rename
命令的path。
如果你没有这个命令,search你的软件包pipe理器来安装它或手动执行
最后但并非最不重要的是,这个工具最初是由Perl的爸爸Larry Wall编写的。
使用find
的解决scheme:
仅重命名文件 :
find /your/target/path/ -type f -exec rename 's/special/regular/' '{}' \;
仅重命名目录 :
find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \+
重命名这两个文件和目录 :
find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+
如果你不介意安装另一个工具,那么你可以使用rnm :
rnm -rs '/special/regular/g' -dp -1 *
它会遍历所有的目录/子目录(因为-dp -1
),并用特殊的名字replace。
@ speakr的回答是我的线索。
如果使用-execdir来转换文件和目录,则还需要从示例中删除-type f
。 拼出来,使用:
find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+
另外,如果你想在给定的文件名中replace所有出现的special
常量,而不仅仅是第一次出现,那么考虑在正则expression式中添加g
(全局)标志。 例如:
find /your/target/path/ -execdir rename 's/special/regular/g' '{}' \+
将special-special.jpg
转换为regular-regular.jpg
。 如果没有全球旗帜,你最终会得到regular-special.jpg
。
仅供参考:在Mac OSX上,默认情况下不安装GNU Rename。 如果你正在使用Homebrew软件包pipe理器 , brew install rename
将解决这个问题。
对于那些只想重命名目录,你可以使用这个命令:
find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;
注意types现在是d
目录,并使用-execdir
。
我一直无法解决如何一次重命名文件和目录。
之前有人评论说,一旦它重命名了根文件夹,它就不能再遍历文件树了。 有一个-d
开关可用于从下往上进行深度遍历,所以最后我会相信:
find -d /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;
从manpage( man find
):
-d Cause find to perform a depth-first traversal, ie, directories are visited in post-order and all entries in a directory will be acted on before the directory itself. By default, find visits directories in pre-order, ie, before their contents. Note, the default is not a breadth-first traversal.