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

$ 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

当前回答

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

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

其他回答

我对这个问题的解决方案是一个bash脚本:

#!/bin/bash
directory=$1
cd "$directory"
while [ "$(find ./ -regex '.* .*' | wc -l)" -gt 0 ];
do filename="$(find ./ -regex '.* .*' | head -n 1)"
mv "$filename" "$(echo "$filename" | sed 's|'" "'|_|g')"
done

只需在执行脚本后将您想要应用脚本的目录名称作为参数。

奈迪姆答案的递归版本。

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

使用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' "{}" \;

使用以下命令将文件名中的空格替换为下划线以及目录名。

find -name "* *" -print0 | sort -rz | \
  while read -d $'\0' f; do mv -v "$f" "$(dirname "$f")/$(basename "${f// /_}")"; done

用于命名为/files文件夹中的文件

for i in `IFS="";find /files -name *\ *`
do
   echo $i
done > /tmp/list


while read line
do
   mv "$line" `echo $line | sed 's/ /_/g'`
done < /tmp/list

rm /tmp/list