我有一些包含不可打印字符的旧迁移文件。我想找到所有具有此类名称的文件并将它们从系统中完全删除。
例子:
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
在此类文件夹中执行操作时看到的示例屏幕截图:
我想找到这些带有不可打印字符的文件并删除它们。
根据这个答案,尝试:
LC_ALL=C find . -regex '.*[^ -~].*' -print # -delete
或者:
LC_ALL=C find . -type f -regex '*[^[:alnum:][:punct:]]*' -print # -delete
注意:文件打印正确后,删除#
字符。
另请参阅:我如何 grep 查找所有非 ASCII 字符。
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
,然后删除文件。
可以将 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 不喜欢管道。
您可以使用 grep 仅打印包含反斜杠的行:
ls -lb | grep \\\\