Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 汇总行和汇总列_Linux_Bash_Shell_Unix_Awk - Fatal编程技术网

Linux 汇总行和汇总列

Linux 汇总行和汇总列,linux,bash,shell,unix,awk,Linux,Bash,Shell,Unix,Awk,我有一个包含以下行的文件: 01323874;291874;-;000000000000003030;2511011999;-;000000000000000000 01323874;291874;-;000000000012920840;2511011999;+;000002910023874000 01323872;291872;-;000000000000008750;2511011999;-;000000000000008750 01323872;291872;+;00000000060

我有一个包含以下行的文件:

01323874;291874;-;000000000000003030;2511011999;-;000000000000000000
01323874;291874;-;000000000012920840;2511011999;+;000002910023874000
01323872;291872;-;000000000000008750;2511011999;-;000000000000008750
01323872;291872;+;000000000609396980;          ;+;000000000000000000
01323778;      ;-;000000000468442930;          ;+;000000000000000000
01323778;      ;+;000000005166500460;          ;+;000000000000000000
01323778;      ;-;000000000469421100;2511021000;+;000000000469421100
01323778;291778;-;000000000361156930;2511021000;-;000000000361156930
01323778;      ;-;000000000186088530;2511021000;+;000000000186088530
01323778;291778;-;000000000017602470;2511021000;-;000000000017602470
我想根据第一列汇总行:

考虑到第3列中的符号(+/-),汇总第4列的值

考虑到第6列中的符号(+/-),汇总第7列的值

01323874;291874;-;000000000012923871;2511011999;+;000002910023874000
01323872;291872;+;000000000609388230;2511011999;-;000000000000008750
01323778;291778;+;000000003663788500;2511021000;+;000000000276750230
我已经成功地生成了格式良好的行,但找不到聚合它们的方法。非常感谢您的帮助

kent$  cat f
01323874;291874;-;000000000000003030;2511011999;-;000000000000000000
01323874;291874;-;000000000012920840;2511011999;+;000002910023874000
01323872;291872;-;000000000000008750;2511011999;-;000000000000008750
01323872;291872;+;000000000609396980;          ;+;000000000000000000
01323778;      ;-;000000000468442930;          ;+;000000000000000000
01323778;      ;+;000000005166500460;          ;+;000000000000000000
01323778;      ;-;000000000469421100;2511021000;+;000000000469421100
01323778;291778;-;000000000361156930;2511021000;-;000000000361156930
01323778;      ;-;000000000186088530;2511021000;+;000000000186088530
01323778;291778;-;000000000017602470;2511021000;-;000000000017602470
输出

kent$  awk -F';' '{a[$1]=(1*$2?$2:a[$1]); b[$1]+=$3=="-"?-$4:$4;
                   c[$1]=(1*$5?$5:c[$1]); d[$1]+=$6=="-"?-$7:$7}
        END{for(x in a)
               printf "%s;%s;%s;%018d;%s;%s;%018d\n",
                        x,a[x],
                        (b[x]>0?"+":"-"),(b[x]<0?-b[x]:b[x]),c[x],
                        (d[x]>0?"+":"-"),(d[x]<0?-d[x]:d[x])}' f
01323872;291872;+;000000000609388230;2511011999;-;000000000000008750
01323778;291778;+;000000003663788500;2511021000;+;000000000276750230
01323874;291874;-;000000000012923870;2511011999;+;000002910023874000
kent$awk-F';“{a[$1]=(1*$2?$2:a[$1]);b[$1]+=$3==“-”?-$4:$4;
c[$1]=(1*$5?$5:c[$1]);d[$1]+=$6==“-”?-$7:$7}
结束{for(a中的x)
printf“%s;%s;%s;%018d;%s;%s;%018d\n”,
x、 a[x],
(b[x]>0?“+”:“-”,(b[x]0?“+”:“-”,(d[x]awk解决方案:

awk -F';' 'function get_sign(n){ 
               return (n<0)? "-":"+" 
           }
           { 
               a[$1]+=int($3$4); b[$1]+=int($6$7); 
               if ($2*1) fld2[$1]=$2; if ($5*1) fld5[$1]=$5 
           }
           END{ 
               for(i in a) print i, fld2[i], get_sign(a[i]),
               sprintf("%018d",(a[i]>0)? a[i]:a[i]*-1), fld5[i], get_sign(b[i]),
               sprintf("%018d",(b[i]>0)? b[i]:b[i]*-1) 
           }' OFS=';' file

  • function get_sign(n){…}
    -函数,定义数值参数
    n
    是正数还是负数,并返回相应的符号

到目前为止您尝试了什么?首先在这里发布您已经完成的代码。第2列和第5列如何?在每个组中,最后一列中的值是如何选择的?我没有看到任何模式。这有关系吗?仅就我个人所知,
1*
的目的是什么?@fzd您将看到是否从代码中删除它。它过滤将黑色但不是空的字符串输出。如
“”
@kent它很好用,谢谢,但是当第2列或第5列只包含空格时,它不会处理这个问题。例如,现在我得到了
01323872;291872;+;000000000609388230;;-;0000000000000008750
但是它应该是
01323872;291872;+;000000000609388230;空格;-;0000000000000008750
它很好用,谢谢,但是它不会处理第2列或第5列只包含空格的情况。例如,现在我得到
01323872;291872;+;000000000609388230;;-;0000000000000008750
,但它应该是
01323872;291872;+;000000000609388230;空格;-;0000000000000008750
@technopathe,这不是真的。我已经测试过这种情况,当第2列只包含空格和它给了我:
01323872;;+;000000000609388230;2511101999;-;00000000000000875001323778;;+;000000003663788500;2511021000;+;000000000276750230 01323874;;;-;00000012923870;251011999;+;000002910023874000
正如预期的那样,实际上我宁愿用这种方式打印空白;******;而不是用这种方式;*指的是空白,我已经解决了ed空间问题
awk-F';''函数get_-sign(n){return(n0)}a[i]:a[i]*-1,fld5[i],get_-sign(b[i]),sprintf(“%018d”,(b[i]>0)?b[i]:b[i]*-1)}OFS=“;”F1>F2
awk'BEGIN OFS=FS=“;”}{$5=sprintf(“%10s”,$5)$2=sprintf(“%10s”,$2)print}'F2>F3
,但仍需要缩小和优化
01323872;291872;+;000000000609388230;2511011999;-;000000000000008750
01323778;291778;+;000000003663788500;2511021000;+;000000000276750230
01323874;291874;-;000000000012923870;2511011999;+;000002910023874000