我的目录和子目录中有多个文件包含 Microsoft 文件共享和 SharePoint 不支持的特殊字符。字符类型多种多样,从波浪号到与号再到谁知道什么。我使用过如下命令:
find . -type f -print | while read file
do
file_clean=$( echo ${file} | tr " \~()&'" "_____" )
mv $file $file_clean
done
并看到有人建议使用 globstar。但我仍然无法找到一个相对简单的命令来删除所有特殊字符,递归地只留下AZ,az,0-9(递归似乎是最难的部分)。
答案1
最简单的方法是桀骜。 Zsh 是基本 OS X 安装的一部分,但需要通过大多数 Linux 发行版上的包管理器进行安装,并从 *BSD 上的端口进行安装。 Zsh 提供了zmv
功能使许多文件重命名任务变得容易。首先运行它(或将其放入您的.zshrc
,以供交互使用):
autoload zmv
然后你可以使用
zmv '(**/)(*)' '$1${2//[^A-Za-z0-9]/_}'
或同等的
zmv '**/*' '$f:h${${f:t}//[^A-Za-z0-9]/_}'
第一个zmv
命令将所有匹配的文件**/*
(即当前目录和子目录中的所有文件递归地)重命名为同一目录 ( $1
) 中的文件,并将基本名称转换为[^A-Za-z0-9]
用_
.括号 导致(**/)(*)
路径的目录部分(直到最后一个/
)被分配给$1
,文件的基本名称被分配给$2
。第二个命令执行相同的操作,但使用$f
引用整个原始名称和修饰语 :h
并:t
提取名称的目录和基本部分。
您的脚本会以各种方式中断,因为它通过 shell 处理来运行各种特殊字符,而不是按字面意思处理它们。要了解原因,请阅读为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?
答案2
要获取所有文件名,您应该依赖空删除字符串:
find /your/path/ -print0 | while read -r -d $'\0' filename; do
dn="`dirname "$filename"`"
bn="`basename "$filename"`"
bn_clean="`echo "$bn" | tr " \~()&'" "_______"`"
file_clean="$dn/$bn_clean"
if [ "$filename" != "$file_clean" ] ; then
mv -fv "$filename" "$file_clean"
fi
done
答案3
小心这一点:
perl -pi -e 's/\W//g' $(find . -type f)
您可以使用以下方法进行备份:
perl -pi.bak -e 's/\W//g' $(find . -type f)