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

Tom*_*Tom 56 linux bash ubuntu find

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

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

spe*_*akr 96

解决方案使用find:

重命名文件:

find /your/target/path/ -type f -exec rename 's/special/regular/' '{}' \;
Run Code Online (Sandbox Code Playgroud)

重命名目录:

find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \+
Run Code Online (Sandbox Code Playgroud)

要重命名文件和目录:

find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+
Run Code Online (Sandbox Code Playgroud)

  • @speakr,很好的解决方案,谢谢!您能否提供有关它正在做什么的更多详细信息,尤其是这部分“'{}'\”?快速护目镜没有帮助,所以我认为这些信息可能对其他人也有用。 (4认同)
  • @DmitryGonchar只需看一下[_find_ manpage]中的`-exec command;`(http://linux.die.net/man/1/find). (2认同)
  • @ThiloSchulz确实如此,但你必须使用`find ... -execdir ...'{}'+`而不是`...'{}'\;`.澄清补充说. (2认同)
  • 在许多文件的情况下,利用查找中的正则表达式,对于上面的最后一个示例,您使用:``find /your/target/path/ -regex '.*special.*' -execdir rename 's/special/regular/ ' '{}' \+``,否则会很慢! (2认同)

Gil*_*not 74

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

shopt -s globstar
rename -n 's/special/regular/' **
Run Code Online (Sandbox Code Playgroud)

-n测试结果正常时,请取下开关

警告 还有其他具有相同名称的工具可能会或可能不会这样做,所以要小心.

如果运行以下命令(GNU)

$ file "$(readlink -f "$(type -p rename)")"
Run Code Online (Sandbox Code Playgroud)

你有一个结果

.../rename: Perl script, ASCII text executable
Run Code Online (Sandbox Code Playgroud)

并且不包含:

ELF
Run Code Online (Sandbox Code Playgroud)

那么这似乎是正确的工具=)

如果没有,为了使它成为默认(通常已经是这种情况)on Debian和衍生出来Ubuntu:

$ sudo update-alternatives --set rename /path/to/rename
Run Code Online (Sandbox Code Playgroud)

(替换/path/to/renameperl's rename命令的路径.


如果您没有此命令,请搜索包管理器以进行安装或手动执行


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

  • 什么是`shopt -s globstar`? (6认同)
  • 我在我的主目录中的目录中有大约1700个文件要重命名.这似乎太多了,这实际上是错误消息中的文本,太多的参数. (4认同)
  • 它可以启用bash功能`**`(代表递归). (3认同)
  • 对我来说也不是递归的 (3认同)

Jah*_*hid 6

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

rnm -rs '/special/regular/g' -dp -1 *
Run Code Online (Sandbox Code Playgroud)

它将遍历所有目录/子目录(因为-dp -1)并在其名称中使用regular替换special.


U00*_*07D 6

@speakr 的回答对我来说是线索。

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

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

另外,g如果您想替换给定文件名中所有出现的specialwithregular而不仅仅是第一次出现的情况,请考虑向正则表达式添加(全局)标志。例如:

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

将转变special-special.jpgregular-regular.jpg. 如果没有全局标志,您最终会得到regular-special.jpg.

仅供参考:Mac OSX 上默认不安装 GNU Rename。如果您使用Homebrew 包管理器brew install rename可以解决这个问题。


jyv*_*vet 5

这是另一种更便携且不依赖命令的方法因为rename它可能需要不同的参数,具体取决于发行版)。

\n\n

它递归地重命名文件和目录:

\n\n
find . -depth -name "*special*" | \\\nwhile IFS= read -r ent; do mv $ent ${ent%special*}regular${ent##*special}; done\n
Run Code Online (Sandbox Code Playgroud)\n\n

它能做什么

\n\n
    \n
  • 使用带有参数的 find通过执行深度优先遍历-depth来重新排序结果(即目录中的所有条目都显示在目录本身之前)。
  • \n
  • 进行模式替换以仅修改路径中最后一次出现的常规项。
  • \n
\n\n

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

\n\n

例子

\n\n

给出以下树:

\n\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 aa-special-aa\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 bb-special\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 special-cc\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 special-dd\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Special-ee\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 special-00\n
Run Code Online (Sandbox Code Playgroud)\n\n

mv它按特定顺序生成这些命令:

\n\n
mv ./aa-special-aa/bb-special/special-cc ./aa-special-aa/bb-special/regular-cc\nmv ./aa-special-aa/bb-special/special-dd ./aa-special-aa/bb-special/regular-dd\nmv ./aa-special-aa/bb-special ./aa-special-aa/bb-regular\nmv ./aa-special-aa ./aa-regular-aa\nmv ./special-00 ./regular-00\n
Run Code Online (Sandbox Code Playgroud)\n\n

获得如下树:

\n\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 aa-regular-aa\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 bb-regular\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 regular-cc\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 regular-dd\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Special-ee\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 regular-00\n
Run Code Online (Sandbox Code Playgroud)\n