PERL 计算不可打印字符

标签 perl ascii non-ascii-characters non-printable

我有 100,000 个文件要分析。具体来说,我想从任意大小的文件样本中计算可打印字符的百分比。其中一些文件来自大型机、Windows、Unix 等,因此很可能包含二进制和控制字符。

我开始使用 Linux 的"file"命令,但它没有为我的目的提供足够的细节。以下代码传达了我正在尝试做的事情,但并不总是有效。

    #!/usr/bin/perl -n

    use strict;
    use warnings;

    my $cnt_n_print = 0;
    my $cnt_print = 0;
    my $cnt_total = 0;
    my $prc_print = 0;

    #Count the number of non-printable characters
    while ($_ =~ m/[^[:print:]]/g) {$cnt_n_print++};

    #Count the number of printable characters
    while ($_ =~ m/[[:print:]]/g) {$cnt_print++};

    $cnt_total = $cnt_n_print + $cnt_print;
    $prc_print = $cnt_print/$cnt_total;

    #Print the # total number of bytes read followed by the % printable
    print "$cnt_total|$prc_print\n"

这是一个有效的测试调用:
    echo "test_string of characters" | /home/user/scripts/prl/s16_count_chars.pl

这是我打算如何称呼它,并且适用于一个文件:
    find /fct/inbound/trans/ -name "TRNST.20121115231358.xf2" -type f -print0 | xargs -0 head -c 2000 | /home/user/scripts/prl/s16_count_chars.pl

这不能正常工作:
    find /fct/inbound/trans/ -type f -print0 | xargs -0 head -c 2000 | /home/user/scripts/prl/s16_count_chars.pl

这也不行:
    find /fct/inbound/trans/ -type f -print0 | xargs -0 head -c 2000 | perl -0 /home/user/scripts/prl/s16_count_chars.pl

它不是为 find 返回的每一行执行一次脚本,而是为所有结果执行一次。

提前致谢。

迄今为止的研究:

管道和 XARGS 和分隔符

http://help.lockergnome.com/linux/help-understand-pipe-xargs--ftopict549399.html

http://en.wikipedia.org/wiki/Xargs#The_separator_problem

说明:
1.) 期望的输出:如果一个目录中有 932 个文件,输出将是一个 932 行的文件名列表,从文件中读取的总字节数和可打印字符的百分比。
2.) 许多文件是二进制的。脚本需要处理嵌入的二进制文件 eoleof序列。
3.) 许多文件很大,所以我只想读取第一个/最后一个 xx 字节。我一直在尝试使用 head -c 256tail -c 128分别读取前 256 个字节或后 128 个字节。解决方案可以在管道中工作或在 perl 脚本中限制字节。

最佳答案

-n选项将您的整个代码包装在 while(defined($_=<ARGV>) { ... } 中堵塞。这意味着您的 my $cnt_print和其他变量声明对每一行输入重复,基本上重置所有变量值。

解决方法是使用全局变量(如果你想继续使用 ouruse strict 声明它们),而不是将它们初始化为 0 ,因为它们会为每一行输入重新初始化。你可以这样说

our $cnt_print //= 0;

如果你不想要 $cnt_print和它的 friend 对于第一行输入是未定义的。

this recent question有类似的问题。

关于PERL 计算不可打印字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13483290/

相关文章:

c++ - 在 C++ 中将 UTF-8 转换为 ANSI

java - 为什么我们在java中使用string.charAt(index) -'a'?

php - 在 PHP 中将非 ASCII 字符打印为十六进制

perl - 我如何使用 Perl 的 Getopt::Long 处理 -r=<pattern>?

arrays - 如何在散列的数组中引用 Perl 散列?

mysql - 有没有办法通过解析文本文件来填写Sharepoint条目?

php - 此 Codeigniter 函数不考虑所有重音字符

perl - 使用 ANSI 转义码查询光标位置

c - ( C ) 在 ASCII 图表中向前步进 x 次但仍保持在 a-z 之间的最佳方法?

c - EBCDIC 到 ASCII 转换背后的基本原理是什么?