我想将包含“special”一词的所有文件和目录重命名为“regular”。它应该保持区分大小写,因此“特殊”不会变成“常规”。
我如何以递归方式执行此操作?
答案 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
开关
还有其他同名工具可能会或可能不会这样做,所以要小心。
如果您运行以下命令(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)
答案 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 manager,brew 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通过执行深度优先遍历对结果进行重新排序(即,目录中的所有条目都显示在目录本身之前)。这样,首先修改文件,然后再修改每个父目录。
示例
给出以下树:
-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)
对于rename
版rename from util-linux 2.23.2
,以下命令对我有用:
find . -type f -exec rename mariadb mariadb-proxy '{}' \;