【问题标题】:perl or awk: zero proof division with perl or awkperl 或 awk:使用 perl 或 awk 进行零证明除法
【发布时间】:2019-05-09 21:46:35
【问题描述】:

我必须添加一个字段来显示文件中两个字段之间的百分比差异,例如:

BI,1266,908
BIL,494,414
BKC,597,380
BOOM,2638,654
BRER,1453,1525
BRIG,1080,763
DCLE,0,775

输出应该是:

BI,1266,908,-28.3%
BIL,494,414,-16.2%
BKC,597,380,-36.35%
BOOM,2638,654,-75.2%
BRER,1453,1525,5%
BRIG,1080,763,-29.4%
DCLE,0,775,-

注意最后一行的零。这些字段中的任何一个都可以为零。如果任一字段中出现零,则可接受 N/A 或 -。

我正在尝试什么--

Perl:

perl -F, -ane 'if ($F[2] > 0 || $F[3] > 0){print $F[0],",",$F[1],",",$F[2],100*($F[2]/$F[3])}' file

我得到Illegal division by zero at -e line 1, <> line 2. 如果我将|| 更改为&&,它不会打印任何内容。

在 awk 中:

awk '$2>0{$4=sprintf("%d(%.2f%)", $3, ($3/$2)*100)}1' file

只打印文件。

【问题讨论】:

    标签: perl awk


    【解决方案1】:
    $ awk -F, '$2 == 0 || $3 == 0 { printf("%s,-\n", $0); next }
               { printf("%s,%.2f%%\n", $0, 100 * ($3 / $2) - 100) }' input.csv
    BI,1266,908,-28.28%
    BIL,494,414,-16.19%
    BKC,597,380,-36.35%
    BOOM,2638,654,-75.21%
    BRER,1453,1525,4.96%
    BRIG,1080,763,-29.35%
    DCLE,0,775,-
    

    工作原理:如果第二列或第三列等于 0,则在该行中添加一个- 字段。否则,计算百分比差异并将其相加。

    【讨论】:

      【解决方案2】:

      您的 perl 的主要问题是混淆了 awk 的基于 1 的列索引和 perl 的基于 0 的列索引。

       perl -F, -ane 'print "$1," if /(.+)/;if ($F[1] > 0 && $F[2] > 0){printf ("%.2f%", ((100*$F[2]/$F[1])-100)) } else {print "-"};print "\n"' file
      

      这里的$1 指的是捕获组(.+),意思是“除了换行之外的整行”。如果您了解 awk,其余部分可能不言自明。

      【讨论】:

        【解决方案3】:

        你没有告诉 awk 字段是用逗号分隔的,所以它假设默认值是空格,所以 $2 永远不会大于零,因为它是 null,因为每行只有 1 个空格分隔的字段。将其更改为:

        $ awk 'BEGIN{FS=OFS=","} $2>0{$4=sprintf("%d(%.2f%)", $3, ($3/$2)*100)}1' file
        BI,1266,908,908(71.72%)
        BIL,494,414,414(83.81%)
        BKC,597,380,380(63.65%)
        BOOM,2638,654,654(24.79%)
        BRER,1453,1525,1525(104.96%)
        BRIG,1080,763,763(70.65%)
        DCLE,0,775
        

        然后调整它以获得您想要的输出:

        $ awk 'BEGIN{FS=OFS=","} {$4=($2 && $3 ? sprintf("%.2f%", (($3/$2)-1)*100) : "N/A")} 1' file
        BI,1266,908,-28.28%
        BIL,494,414,-16.19%
        BKC,597,380,-36.35%
        BOOM,2638,654,-75.21%
        BRER,1453,1525,4.96%
        BRIG,1080,763,-29.35%
        DCLE,0,775,N/A
        

        【讨论】:

        • 我想说的最干净的解决方案——为什么不做他们实际的“desired output”,($3/$2-1)*100...?
        • @zdim 我没有注意到有什么不同,我只是专注于修复他们的 awk 代码来做他们想做的事情。现已修复,谢谢。
        猜你喜欢
        • 1970-01-01
        • 2011-08-04
        • 2012-11-30
        • 2012-09-29
        • 2014-03-19
        • 2014-02-02
        • 2015-05-05
        • 2012-11-27
        • 1970-01-01
        相关资源
        最近更新 更多