从递归 Linux 文件系统中删除无效字符

从递归 Linux 文件系统中删除无效字符

我有一个巨大的文件系统,其中充满了使用无效字符的文件夹/文件。

我发现一个命令几乎可以满足我的要求,它来自这个线程 -https://stackoverflow.com/questions/40712263/how-to-remove-special-characters-in-file-names

有问题的命令如下。

for file in *; do mv "$file" $(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g'); done &

这会删除所有非字母数字、连字符下划线、带下划线的句号(句号)的内容。

我需要让这个命令忽略空格而不是用下划线替换空格。

我尝试过诸如此类的变体。

for file in *; do mv "$file" $(echo "$file" | sed -e 's/[^A-Za-z0-9._- ]/_/g'); done & 

我在 [] 中添加了一个空格,但当然,事情永远不会那么简单。

本质上,除非文件/文件夹使用字母数字、连字符、下划线、空格或句点/句号,否则我希望所有其他字符都替换为下划线。

我如何修改上面的命令以忽略空格以及其他字符,或者是否有更好的方法来做到这一点?不幸的是,重命名命令在此服务器上不起作用,这限制了我发现的一些其他解决方案。

答案1

使用find珀尔的rename:

find . -depth -exec rename -n 's/[^\w .-]/_/g' {} +

-n当对输出满意时删除。

这是递归的, 和:

LESS='+/^ +-depth' man find

-depth在处理目录本身之前处理每个目录的内容。

答案2

字符类-中的 表示字符范围。通过写作,.-你是在说“匹配以 开头.和结尾的每个字符,这根本不是字符,因为来自 .

为了匹配文字-字符,您需要

  • 逃避它:\-
  • 将其放在字符类的第一位,或者
  • 将其放在字符类的最后。

所以,

for file in *; do mv "$file" $(echo "$file" | sed -e 's/[^A-Za-z0-9._ -]/_/g'); done &

应该做你想做的事。

相关内容