2011-11-09 70 views

回答

1

是的,只是cd到/目录和:

find -depth -type d -execdir rename 's/_/ /g' {} \; 

根据不同的发行版,你需要perl的重命名(有时女士prename)。

如果

file $(type -p rename) 

输出包含ELF,看起来不好;)

编辑 -depth和-execdir加入

+1

这不会起作用,因为“foo_bar这样的名称”会被发现之前更名为“foo_bar这样的名称/ baz_quux”是'find'输出 - 后者不会在尝试重命名时找到。 –

+0

没什么大不了的,您可以添加'-depth'开关来查找。 –

+0

是的,-depth加入了;) –

6

使用-execdir是简单的答案,而只是会与支持-execdir的版本find一起工作,如GNU查找,因为POSIX only specifies -exec

如果你只是想使用bash,这是令人惊讶的棘手,因为你正在重命名目录find正在通过搜索。即使你获得订单的权利,通过-depth选项find,你需要确保你只改写了路径的最后一个组件,每个-exec。以下是one of the examples given in the Bash FAQ一个微不足道的变化,似乎为我工作确定:

find . -depth -name "*_*" -exec bash -c 'dir=${1%/*} base=${1##*/}; mv "$1" "$dir/${base//_/ }"' _ {} \; 

这常见问题回答了有关递归命名的文件夹可能会感兴趣的问题进行更多的讨论。


更新:由于一个班轮是相当复杂的,它可能是值得打破下来一点点在解释的利益。本质上,find命令是:

find . -depth -name "*_*" -exec bash -c [SOME-STUFF] _ {} \; 

换句话说,发现所有这些包含下划线,并且对于每个这样的目录,从最深的目录,作为_运行bash脚本[SOME-STUFF],具有参数0(以表明我们不关心它)和参数1作为找到的文件的名称。 (find-exec后取代{}文件名中的\;刚刚结束的命令-exec运行。)

然后[SOME-STUFF]部分组成:

dir=${1%/*} 

...其中,使用parameter expansion,将从$1(文件名)的末尾删除/*的最短匹配并将dir设置为结果。同样,这一部分:

base=${1##*/} 

...从$1开始删除的*/最长匹配,并设置base的结果。所以base只是路径的最后一个组件。

mv "$1" "$dir/${base//_/ }" 

这再次使用参数扩展,此时用${parameter/pattern/string}语法:

然后更名实际上是由mv命令,这是完成。文件名($1)被重命名为$dir,后面跟着$base,但是每个下划线在$base被替换为一个空格。

+0

如果您希望替换值(本例中为空格)是源自调用脚本的变量,该怎么办?在前。我已经包含$ SOMEVAR不起作用。找 。 -depth -name“* _ *”-exec bash -c'dir = $ {1%/ *} base = $ {1 ## * /}; mv“$ 1”“$ dir/$ {base // _/$ SOMEVAR}”'_ {} \; –

0

如果你有bash4,你可以运行:

for i in **; do [[ -d "$i" ]] || continue; mv "$i" "${i/_/ }"; done 
相关问题