perl或awk:用perl或awk进行零证明除法

时间:2019-05-08 23:28:26

标签: perl awk

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

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

仅打印文件。

3 个答案:

答案 0 :(得分:3)

$ 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,则向该行添加一个-字段。否则,计算百分比差异并将其相加。

答案 1 :(得分:3)

您的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,其余的内容可能不言自明。

答案 2 :(得分:2)

您不是在告诉awk字段之间用逗号隔开,因此它假设默认值是空格,因此$ 2永远不会大于零,因为它是空的,因为每行只有一个空格分隔的字段。更改为:

$ 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
相关问题