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

$ 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

当前回答

find . -depth -name '* *' \
| while IFS= read -r f ; do mv -i "$f" "$(dirname "$f")/$(basename "$f"|tr ' ' _)" ; done

一开始我没有把它弄好,因为我没有想到目录。

其他回答

对于那些使用macOS的人来说,首先安装所有的工具:

 brew install tree findutils rename

然后当需要重命名时,将GNU find (gfind)的别名改为find。然后运行@Michel Krelin的代码:

alias find=gfind 
find . -depth -name '* *' \
| while IFS= read -r f ; do mv -i "$f" "$(dirname "$f")/$(basename "$f"|tr ' ' _)" ; done   

实际上,在perl中不需要使用重命名脚本:

find . -depth -name "*[[:space:]]*" -execdir bash -c 'mv "$1" `echo $1 | sed s/[[:space:]]/_/g`' -- {} \;

奈迪姆答案的递归版本。

find . -name "* *" | awk '{ print length, $0 }' | sort -nr -s | cut -d" " -f2- | while read f; do base=$(basename "$f"); newbase="${base// /_}"; mv "$(dirname "$f")/$(basename "$f")" "$(dirname "$f")/$newbase"; done

In一样

就像选择的答案一样。

brew install rename

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

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

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