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

$ 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.ul使用这个命令:

因为I在*' '*;做重命名。Ul ' ' '_' *;完成

其他回答

你可以用这个:

find . -depth -name '* *' | while read fname 

do
        new_fname=`echo $fname | tr " " "_"`

        if [ -e $new_fname ]
        then
                echo "File $new_fname already exists. Not replacing $fname"
        else
                echo "Creating new file $new_fname to replace $fname"
                mv "$fname" $new_fname
        fi
done

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

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

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

递归版本的一个简单替代方法是逐步增加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

对于那些使用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