20

我有一些包含不可打印字符的旧迁移文件。我想找到所有具有此类名称的文件并将它们从系统中完全删除。

例子:

ls -l
-rwxrwxr-x 1 cws cws      0 Dec 28  2011 ??"??

ls -lb
-rwxrwxr-x 1 cws cws      0 Dec 28  2011 \a\211"\206\351

我想找到所有这些文件。

这是我ls在此类文件夹中执行操作时看到的示例屏幕截图:

在此处输入图像描述

我想找到这些带有不可打印字符的文件并删除它们。

4

5 回答 5

31
于 2013-10-02T21:02:10.297 回答
5

根据这个答案,尝试:

LC_ALL=C find . -regex '.*[^ -~].*' -print # -delete

或者:

LC_ALL=C find . -type f -regex '*[^[:alnum:][:punct:]]*' -print # -delete

注意:文件打印正确后,删除#字符。

另请参阅:我如何 grep 查找所有非 ASCII 字符

于 2018-04-12T22:50:06.067 回答
3

find到现在为止,您可能已经解决了您的问题,但它对我的情况并不适用,因为我使用-regex开关时没有显示文件。所以我使用ls. 希望它对某人有用。

基本上,对我有用的是:

ls -1 -R -i | grep -a "[^A-Za-z0-9_.':@ /-]" | while read f; do inode=$(echo "$f" | cut -d ' ' -f 1); find -inum "$inode" -delete; done

把它分成几部分:

ls -1 -R -i

这将递归地 ( -R) 列出 ( ls) 当前目录下的文件,每行一个文件 ( -1),在每个文件前加上其 inode 编号 ( -i)。结果将通过管道传送到grep.

grep -a "[^A-Za-z0-9_.':@ /-]"

过滤每个条目,将每个输入视为文本 ( -a),即使它最终是二进制的。grep如果一行包含与列表中指定的字符不同的字符,则让行通过。结果将通过管道传送到while.

while read f
do
    inode=$(echo "$f" | cut -d ' ' -f 1)
    find -inum "$inode" -delete
done

while将遍历所有条目,提取 inode 编号并将 inode 传递给find,然后删除文件。

于 2016-05-06T14:35:12.413 回答
1

可以将 PCRE 与 grep -P 一起使用,但不能与 find 一起使用(不幸的是)。您可以使用 exec 与 grep 链接查找。使用 PCRE(perl 正则表达式),我们可以使用 ascii 类并找到任何非 ascii 的字符。

find . -type f -exec sh -c "echo \"{}\" | grep -qP '[^[:ascii:]]'" \; -exec rm {} \;

除非第一个返回非错误代码,否则以下 exec 将不会执行。在这种情况下,这意味着表达式与文件名匹配。我使用 sh -c 因为 -exec 不喜欢管道。

于 2017-10-28T20:28:12.770 回答
0

您可以使用 grep 仅打印包含反斜杠的行:

ls -lb | grep \\\\
于 2013-10-02T20:53:54.403 回答