我有一个巨大的文件系统,其中充满了使用无效字符的文件夹/文件。
我发现一个命令几乎可以满足我的要求,它来自这个线程 -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 &
应该做你想做的事。