谁能推荐一个安全的解决方案来递归地用下划线替换从给定根目录开始的文件和目录名中的空格?例如:

$ tree
.
|-- a dir
|   `-- file with spaces.txt
`-- b dir
    |-- another file with spaces.txt
    `-- yet another file with spaces.pdf

就变成:

$ tree
.
|-- a_dir
|   `-- file_with_spaces.txt
`-- b_dir
    |-- another_file_with_spaces.txt
    `-- yet_another_file_with_spaces.pdf

当前回答

使用rename(又名prename),这是一个Perl脚本,可能已经在您的系统上了。分两步:

find . -name "* *" -type d | rename 's/ /_/g'    # do the directories first
find . -name "* *" -type f | rename 's/ /_/g'

基于Jürgen的回答,能够使用“Revision 1.5 1998/12/18 16:16:31 rmb1”版本的/usr/bin/rename (Perl脚本)在单一边界内处理多层文件和目录:

find /tmp/ -depth -name "* *" -execdir rename 's/ /_/g' "{}" \;

其他回答

递归版本的一个简单替代方法是逐步增加for循环的范围(n个子级别n次,与每一级别上的子目录数量无关)。即从最外层的目录运行这些。

for f in *; do mv "$f" "${f// /_}"; done 

for f in */*; do mv "$f" "${f// /_}"; done 

for f in */*/*; do mv "$f" "${f// /_}"; done 

要检查/理解正在执行的操作,请在上述步骤前后运行以下操作。

for f in *;do echo $f;done 

for f in */*;do echo $f;done 

for f in */*/*;do echo $f;done 

我只是为我自己的目的做了一个。 你可以把它作为参考。

#!/bin/bash
cd /vzwhome/c0cheh1/dev_source/UB_14_8
for file in *
do
    echo $file
    cd "/vzwhome/c0cheh1/dev_source/UB_14_8/$file/Configuration/$file"
    echo "==> `pwd`"
    for subfile in *\ *; do [ -d "$subfile" ] && ( mv "$subfile" "$(echo $subfile | sed -e 's/ /_/g')" ); done
    ls
    cd /vzwhome/c0cheh1/dev_source/UB_14_8
done

这只查找当前目录中的文件并重命名它们。我给它加了个别名。

查找。/ name "* *" -type f -d 1 | perl -ple '$file = $_;$file =~ s/\s+/_/g;重命名($ _ $文件);

查找/重命名解决方案。Rename是util-linux的一部分。

你需要先降低深度,因为一个空白文件名可以是空白目录的一部分:

find /tmp/ -depth -name "* *" -execdir rename " " "_" "{}" ";"

使用rename(又名prename),这是一个Perl脚本,可能已经在您的系统上了。分两步:

find . -name "* *" -type d | rename 's/ /_/g'    # do the directories first
find . -name "* *" -type f | rename 's/ /_/g'

基于Jürgen的回答,能够使用“Revision 1.5 1998/12/18 16:16:31 rmb1”版本的/usr/bin/rename (Perl脚本)在单一边界内处理多层文件和目录:

find /tmp/ -depth -name "* *" -execdir rename 's/ /_/g' "{}" \;