在ubuntu / bash下递归重命名文件和目录

时间:2013-02-21 21:32:17

标签: linux bash ubuntu find

我想将包含“special”一词的所有文件和目录重命名为“regular”。它应该保持区分大小写,因此“特殊”不会变成“常规”。

我如何以递归方式执行此操作?

8 个答案:

答案 0 :(得分:91)

使用find的解决方案:

仅重命名文件

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/' '{}' \+

答案 1 :(得分:73)

尝试这样做(需要bash --version> = 4):

shopt -s globstar
rename -n 's/special/regular/' **

在测试结果正常时删除-n开关

warning 还有其他同名工具可能会或可能不会这样做,所以要小心。

如果您运行以下命令(GNU

$ file "$(readlink -f "$(type -p rename)")"

你有一个像

的结果
.../rename: Perl script, ASCII text executable

且不包含:

ELF

然后这似乎是正确的工具=)

如果没有,请将其设为Debian上的默认值(通常已经是这种情况)和Ubuntu之类的衍生物:

$ sudo update-alternatives --set rename /path/to/rename

(将/path/to/rename替换为perl's rename命令的路径。


如果您没有此命令,请搜索软件包管理器进行安装或do it manually


最后但并非最不重要的是,这个工具最初是由Perl的父亲Larry Wall编写的。

答案 2 :(得分:6)

如果您不介意安装其他工具,则可以使用rnm

rnm -rs '/special/regular/g' -dp -1 *

它将遍历所有目录/子目录(因为-dp -1)并将特殊替换为其名称中的常规

答案 3 :(得分:2)

@speakr's answer是我的线索。

如果使用-execdir转换文件和目录,您还需要从显示的示例中删除-type f。要拼写出来,请使用:

find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+

另外,如果要在给定文件名中将g的{​​{1}}替换为special,请考虑向正则表达式添加regular(全局)标记不只是第一次出现。例如:

find /your/target/path/ -execdir rename 's/special/regular/g' '{}' \+

会将special-special.jpg转换为regular-regular.jpg。如果没有全球旗帜,您最终会得到regular-special.jpg

仅供参考:默认情况下,Mac OSX上未安装GNU重命名。如果您使用Homebrew package managerbrew install rename将解决此问题。

答案 4 :(得分:1)

正如Rui Seixas Monteiro所提到的,最好将-iregex模式选项与Find命令一起使用。我发现了以下作品,并在U007D提到的正则表达式中包含了全局标志:

文件:

find /path/ -type f -iregex '.*special.*' -execdir rename 's/special/regular/g' '{}' \+;

目录:

find /path/ -type d -iregex '.*special.*' -execdir rename 's/special/regular/g' '{}' \+;

文件和目录

find /path/ -iregex '.*special.*' -execdir rename 's/special/regular/g' '{}' \+;

答案 5 :(得分:0)

对于那些只想重命名目录的人,可以使用以下命令:

find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;

目录的注释类型现为d,并使用-execdir

我一直无法解决如何在一次传递中重命名文件和目录的问题。

之前有人评论说,一旦重命名根文件夹,它就不能再遍历文件树了。有一个-d开关可以自下而上进行深度遍历,所以我相信根目录会被重命名:

find -d /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;

从联机帮助页(man find):

 -d      Cause find to perform a depth-first traversal, i.e., 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, i.e., before their contents.  Note, the
         default is not a breadth-first traversal.

答案 6 :(得分:0)

这是另一种方法,可移植性更高,并且不依赖于Game.spawns['HQ'].spawnCreep([MOVE,CARRY,WORK],name,{memory:{role:'r'}}); 命令(因为根据发行版可能需要不同的参数)。

它以递归方式重命名文件和目录:

rename

功能

  • 使用带有find . -depth -name "*special*" | \ while IFS= read -r ent; do mv $ent ${ent%special*}regular${ent##*special}; done 参数的find通过执行深度优先遍历对结果进行重新排序(即,目录中的所有条目都显示在目录本身之前)。
  • 执行模式替换仅修改路径中 regular 的最后一次出现。

这样,首先修改文件,然后再修改每个父目录。

示例

给出以下树:

-depth

它以特定顺序生成这些├── aa-special-aa │ └── bb-special │ ├── special-cc │ ├── special-dd │ └── Special-ee └── special-00 命令:

mv

要获取以下树:

mv ./aa-special-aa/bb-special/special-cc ./aa-special-aa/bb-special/regular-cc
mv ./aa-special-aa/bb-special/special-dd ./aa-special-aa/bb-special/regular-dd
mv ./aa-special-aa/bb-special ./aa-special-aa/bb-regular
mv ./aa-special-aa ./aa-regular-aa
mv ./special-00 ./regular-00

答案 7 :(得分:0)

对于renamerename from util-linux 2.23.2,以下命令对我有用:

find . -type f -exec rename mariadb mariadb-proxy '{}' \;