查找并删除具有非 ASCII 名称的文件

11 浏览
0 Comments

查找并删除具有非 ASCII 名称的文件

我有一些包含非可打印字符的旧迁移文件。我想找到所有这些文件,并从系统中彻底删除它们。\n例如:\n

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

\n我想找到所有这样的文件。\n这是我在这些文件夹中执行ls时看到的示例屏幕截图:\n\"enter\n我想找到这些包含非可打印字符的文件并将其删除。

0
0 Comments

通过使用ls命令和grep命令的组合,可以找到和删除非ASCII名称的文件。下面是具体的解决方法:

首先,使用ls命令来列出当前目录下的所有文件,并将每个文件的inode号添加到前缀。命令如下:

ls -1 -R -i

接下来,使用grep命令进行过滤,只保留包含指定字符列表之外字符的行。由于输入可能包含二进制字符,所以需要使用-a选项将输入视为文本。命令如下:

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

最后,使用while循环遍历每一行,提取出inode号,并将其传递给find命令进行文件删除。命令如下:

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

这样,就可以找到并删除非ASCII名称的文件。希望对大家有所帮助。

0
0 Comments

在使用find命令查找和删除文件时,可能会遇到文件名包含非ASCII字符的问题。这种情况下,常规的find命令可能无法正常工作,因为默认情况下,find命令使用的语言环境不支持非ASCII字符。

为了解决这个问题,可以通过设置LC_ALL环境变量为C来修改find命令的语言环境。具体的解决方法如下:

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

或者:

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

这两个命令可以通过设置LC_ALL环境变量为C来查找和删除文件名中包含非ASCII字符的文件。其中,第一个命令使用正则表达式'.*[^ -~].*'来匹配包含非ASCII字符的文件名,第二个命令使用正则表达式'*[^[:alnum:][:punct:]]*'来匹配包含非ASCII字符的文件名。在执行这两个命令之前,需要先将打印出来的文件名正确无误后,再移除命令中的#字符,以实际删除文件。

如果想要了解更多关于如何在grep中查找所有非ASCII字符的信息,可以参考这个链接:How do I grep for all non-ASCII characters

0
0 Comments

非ASCII字符是指ASCII字符代码大于0x7F的字符。这包括大部分UTF-8字符,因为ASCII字符实际上是UTF-8的一个子集。如果删除包含非ASCII字符的文件,可能会误删其他语言命名的合法文件。

ASCII控制字符是指ASCII字符代码在0x00到0x1F和0x7F之间的控制字符,比如ESC(0x1B)。在默认情况下,ls命令将所有控制字符显示为问号,除非使用--show-control-chars选项。猜测你想要删除的文件包含ASCII控制字符,而不是非ASCII字符。

POSIX提供了一系列处理这些字符的字符类。其中,[:cntrl:]表示控制字符,[:graph:]表示可打印的图形字符(不包括空格字符),[:print:]表示可打印字符(包括空格字符)。

Perl兼容正则表达式(PCRE)允许使用十六进制字符代码,语法为\x00。PCRE还提供了[:ascii:]字符类,是[\x00-\x7F]的简写。GNU的grep支持PCRE(使用-P选项),但BSD的grep不支持。GNU和BSD的find命令都不支持PCRE正则表达式。

要查找文件名中包含非打印控制字符的文件,可以使用GNU的find命令,使用POSIX正则表达式,命令如下:

find -type f -regextype posix-basic -regex '^.*/[^/]*[[:cntrl:]][^/]*$'

要删除匹配的文件,只需在find命令中添加-delete选项:

find -type f -regextype posix-basic -regex '^.*/[^/]*[[:cntrl:]][^/]*$' -delete

强烈建议在使用-delete选项之前先运行不带-delete的命令,以便查看将被删除的内容。

如果还想查看正在删除的内容,可以添加-print选项:

find -type f -regextype posix-basic -regex '^.*/[^/]*[[:cntrl:]][^/]*$' -print -delete

如果要删除包含控制字符的路径(文件或目录),可以简化正则表达式,并且不需要-type选项:

find -regextype posix-basic -regex '.*[[:cntrl:]].*' -print -delete

更新:查找非ASCII和控制字符

如果文件名既包含非ASCII字符又包含ASCII控制字符,则可以使用PCRE正则表达式。通过使用find命令遍历目录树,并将结果传递给Perl进行处理。

为了处理可能包含换行符的文件名,需要在find命令中使用-print0选项,并在Perl代码中添加-0标志来指定记录之间的分隔符。以下命令将递归打印当前目录中的所有路径:

find . -print0 | perl -n0e 'print $_, "\n"'

以下是匹配包含非ASCII或非打印(即控制)字符的名称的PCRE正则表达式:

[[:^ascii:][:cntrl:]]

以下命令将打印当前目录中与该正则表达式匹配的所有路径(包括目录和文件):

find . -print0 | perl -n0e 'chomp; print $_, "\n" if /[[:^ascii:][:cntrl:]]/'

要删除匹配的文件和目录,可以使用以下命令:

find . -print0 | perl -MFile::Path=remove_tree -n0e 'chomp; remove_tree($_, {verbose=>1}) if /[[:^ascii:][:cntrl:]]/'

此命令还会打印删除的内容,但控制字符会被解释,因此输出与ls命令的输出不完全匹配。

此外,还可以使用[:print:]或[:graph:]字符类进行匹配。

0