Unix awk计数和基于板的总和:

Unix awk计数和基于板的总和:,unix,awk,Unix,Awk,如果第一个文件的第四个字段在以下范围内,则要从第一个文件(GunZip*.gz i.e Input.csv.gz)中提取所有行 第二个文件(Slab.csv)第一个字段(开始范围)和第二个字段(结束范围),然后填充第一个文件的按板计算的行数以及第四和第五个字段的总和 Input.csv.gz(GunZip) Slab.csv StartRange,EndRange 0,0 1,10 11,100 101,200 201,300 301,400 401,500 501,10000 预期产出: S

如果第一个文件的第四个字段在以下范围内,则要从第一个文件(GunZip*.gz i.e Input.csv.gz)中提取所有行 第二个文件(Slab.csv)第一个字段(开始范围)和第二个字段(结束范围),然后填充第一个文件的按板计算的行数以及第四和第五个字段的总和

Input.csv.gz(GunZip)

Slab.csv

StartRange,EndRange
0,0
1,10
11,100
101,200
201,300
301,400
401,500
501,10000
预期产出:

StartRange,EndRange,Count,Sum-4,Sum-5
0,0,3,0,0
1,10,NotFound,NotFound,NotFound
11,100,1,98,1
101,200,3,474,4
201,300,1,205,3
301,400,NotFound,NotFound,NotFound
401,500,2,905,4
501,10000,1,642,3
我使用以下两个命令来获得上述输出,除了“NotFound”情况


如果建议使用一个线性命令来实现预期的输出,请不要使用perl、python访问。

这里有一种使用
awk
sort
的方法:

awk '
BEGIN { 
    FS = OFS = SUBSEP = ",";
    print "StartRange,EndRange,Count,Sum-4,Sum-5" 
} 
FNR == 1 { next }
NR == FNR {
    ranges[$1,$2]++;
    next
}
{
    for (range in ranges) {
        split(range, tmp, SUBSEP); 
        if ($4 >= tmp[1] && $4 <= tmp[2]) {
            count[range]++;
            sum4[range]+=$4;
            sum5[range]+=$5; 
            next
        }
    }
}
END {
    for(range in ranges) 
        print range, (count[range]?count[range]:"NotFound"), (sum4[range]?sum4[range]:"NotFound"), (sum5[range]?sum5[range]:"NotFound") | "sort -t, -nk1,2"
}' slab input
StartRange,EndRange,Count,Sum-4,Sum-5
0,0,3,NotFound,NotFound
1,10,NotFound,NotFound,NotFound
11,100,1,98,1
101,200,3,474,4
201,300,1,205,3
301,400,NotFound,NotFound,NotFound
401,500,2,905,4
501,10000,1,642,3
awk'
开始{
FS=OFS=subsp=“,”;
打印“起始、结束、计数、和-4、和-5”
} 
FNR==1{next}
NR==FNR{
范围[$1,$2]++;
下一个
}
{
用于(范围内的范围){
分割(射程、tmp、水下);

如果($4>=tmp[1]&&$4,这里有一种方法使用
awk
sort

awk '
BEGIN { 
    FS = OFS = SUBSEP = ",";
    print "StartRange,EndRange,Count,Sum-4,Sum-5" 
} 
FNR == 1 { next }
NR == FNR {
    ranges[$1,$2]++;
    next
}
{
    for (range in ranges) {
        split(range, tmp, SUBSEP); 
        if ($4 >= tmp[1] && $4 <= tmp[2]) {
            count[range]++;
            sum4[range]+=$4;
            sum5[range]+=$5; 
            next
        }
    }
}
END {
    for(range in ranges) 
        print range, (count[range]?count[range]:"NotFound"), (sum4[range]?sum4[range]:"NotFound"), (sum5[range]?sum5[range]:"NotFound") | "sort -t, -nk1,2"
}' slab input
StartRange,EndRange,Count,Sum-4,Sum-5
0,0,3,NotFound,NotFound
1,10,NotFound,NotFound,NotFound
11,100,1,98,1
101,200,3,474,4
201,300,1,205,3
301,400,NotFound,NotFound,NotFound
401,500,2,905,4
501,10000,1,642,3
awk'
开始{
FS=OFS=subsp=“,”;
打印“起始、结束、计数、和-4、和-5”
} 
FNR==1{next}
NR==FNR{
范围[$1,$2]++;
下一个
}
{
用于(范围内的范围){
分割(射程、tmp、水下);

如果($4>=tmp[1]&&$4,这里有另一个使用
perl
的选项,它利用了创建多维数组和散列的好处

perl -F, -lane'
BEGIN {
    $x = pop; 
    ## Create array of arrays from start and end ranges
    ## $range = ( [0,0] , [1,10] ... )
    (undef, @range)= map { chomp; [split /,/] } <>; 
    @ARGV = $x;
}
## Skip the first line
next if $. ==1; 
## Create hash of hash
## $line = '[0,0]' => { "count" => counts , "sum4" => sum_of_col4 , "sum5" => sum_of_col5 }
for (@range) { 
  if ($F[3] >= $_->[0] && $F[3] <= $_->[1]) { 
    $line{"@$_"}{"count"}++; 
    $line{"@$_"}{"sum4"} +=$F[3]; 
    $line{"@$_"}{"sum5"} +=$F[4];
  } 
} 
}{ 
  print "StartRange,EndRange,Count,Sum-4,Sum-5"; 
  print join ",", @$_, 
  $line{"@$_"}{"count"} //"NotFound",  
  $line{"@$_"}{"sum4"}  //"NotFound", 
  $line{"@$_"}{"sum5"}  //"NotFound" 
    for @range
' slab input
StartRange,EndRange,Count,Sum-4,Sum-5
0,0,3,0,0
1,10,NotFound,NotFound,NotFound
11,100,1,98,1
101,200,3,474,4
201,300,1,205,3
301,400,NotFound,NotFound,NotFound
401,500,2,905,4
501,10000,1,642,3
perl-F,-lane'
开始{
$x=流行音乐;
##从开始和结束范围创建数组数组
##$range=([0,0],[1,10]…)
(undef,@range)=映射{chomp;[split/,/]};
@ARGV=$x;
}
##跳过第一行
如果$.==1,则为下一步;
##创建散列的散列
##$line='[0,0]=>{“count”=>counts,“sum4”=>col4的sum\u,“sum5”=>col5的sum\u}
对于(@range){
如果($F[3]>=$->[0]&&$F[3][1]){
$line{“@$\}{“count”}++;
$line{“@${”sum4}+=$F[3];
$line{“@${”sum5}+=$F[4];
} 
} 
}{ 
打印“起始、结束、计数、和-4、和-5”;
打印联接“,”,@$\,
$line{“@${”}{“count”}/“NotFound”,
$line{“@${”}{“sum4”}/“NotFound”,
$line{“@$\}{“sum5}/“NotFound”
对于@range
'板输入
起点、终点、计数、和4、和5
0,0,3,0,0
1,10,找不到,找不到,找不到
11,100,1,98,1
101,200,3,474,4
201,300,1,205,3
301400,找不到,找不到,找不到
401,500,2,905,4
501,10000,1,642,3

这里是另一个使用
perl
的选项,它利用了创建多维数组和散列的好处

perl -F, -lane'
BEGIN {
    $x = pop; 
    ## Create array of arrays from start and end ranges
    ## $range = ( [0,0] , [1,10] ... )
    (undef, @range)= map { chomp; [split /,/] } <>; 
    @ARGV = $x;
}
## Skip the first line
next if $. ==1; 
## Create hash of hash
## $line = '[0,0]' => { "count" => counts , "sum4" => sum_of_col4 , "sum5" => sum_of_col5 }
for (@range) { 
  if ($F[3] >= $_->[0] && $F[3] <= $_->[1]) { 
    $line{"@$_"}{"count"}++; 
    $line{"@$_"}{"sum4"} +=$F[3]; 
    $line{"@$_"}{"sum5"} +=$F[4];
  } 
} 
}{ 
  print "StartRange,EndRange,Count,Sum-4,Sum-5"; 
  print join ",", @$_, 
  $line{"@$_"}{"count"} //"NotFound",  
  $line{"@$_"}{"sum4"}  //"NotFound", 
  $line{"@$_"}{"sum5"}  //"NotFound" 
    for @range
' slab input
StartRange,EndRange,Count,Sum-4,Sum-5
0,0,3,0,0
1,10,NotFound,NotFound,NotFound
11,100,1,98,1
101,200,3,474,4
201,300,1,205,3
301,400,NotFound,NotFound,NotFound
401,500,2,905,4
501,10000,1,642,3
perl-F,-lane'
开始{
$x=流行音乐;
##从开始和结束范围创建数组数组
##$range=([0,0],[1,10]…)
(undef,@range)=映射{chomp;[split/,/]};
@ARGV=$x;
}
##跳过第一行
如果$.==1,则为下一步;
##创建散列的散列
##$line='[0,0]=>{“count”=>counts,“sum4”=>col4的sum\u,“sum5”=>col5的sum\u}
对于(@range){
如果($F[3]>=$->[0]&&$F[3][1]){
$line{“@$\}{“count”}++;
$line{“@${”sum4}+=$F[3];
$line{“@${”sum5}+=$F[4];
} 
} 
}{ 
打印“起始、结束、计数、和-4、和-5”;
打印联接“,”,@$\,
$line{“@${”}{“count”}/“NotFound”,
$line{“@${”}{“sum4”}/“NotFound”,
$line{“@$\}{“sum5}/“NotFound”
对于@range
'板输入
起点、终点、计数、和4、和5
0,0,3,0,0
1,10,找不到,找不到,找不到
11,100,1,98,1
101,200,3,474,4
201,300,1,205,3
301400,找不到,找不到,找不到
401,500,2,905,4
501,10000,1,642,3

非常感谢@mpapec。非常棒的反馈。
/
在我的古老的
perl
工作时(5.8.8)似乎不起作用。将在家里测试它。非常感谢。
:)
。检查
plenv
,您的主文件夹中可以有v5.20或任何其他版本。感谢@mpapec的链接。我以前一直在努力使用local::lib。下周将尝试此功能。非常感谢@mpapec。非常棒的反馈。
/
在我的工作(5.8.8)中对我古老的
perl
似乎不起作用。将在家中进行测试。非常感谢。。非常感谢。
:)
。检查
plenv
,您的主文件夹中可以有v5.20或任何其他版本。感谢@mpapec提供的链接。我以前一直在使用local::lib。下周将尝试此功能。
perl -F, -lane'
BEGIN {
    $x = pop; 
    ## Create array of arrays from start and end ranges
    ## $range = ( [0,0] , [1,10] ... )
    (undef, @range)= map { chomp; [split /,/] } <>; 
    @ARGV = $x;
}
## Skip the first line
next if $. ==1; 
## Create hash of hash
## $line = '[0,0]' => { "count" => counts , "sum4" => sum_of_col4 , "sum5" => sum_of_col5 }
for (@range) { 
  if ($F[3] >= $_->[0] && $F[3] <= $_->[1]) { 
    $line{"@$_"}{"count"}++; 
    $line{"@$_"}{"sum4"} +=$F[3]; 
    $line{"@$_"}{"sum5"} +=$F[4];
  } 
} 
}{ 
  print "StartRange,EndRange,Count,Sum-4,Sum-5"; 
  print join ",", @$_, 
  $line{"@$_"}{"count"} //"NotFound",  
  $line{"@$_"}{"sum4"}  //"NotFound", 
  $line{"@$_"}{"sum5"}  //"NotFound" 
    for @range
' slab input
StartRange,EndRange,Count,Sum-4,Sum-5
0,0,3,0,0
1,10,NotFound,NotFound,NotFound
11,100,1,98,1
101,200,3,474,4
201,300,1,205,3
301,400,NotFound,NotFound,NotFound
401,500,2,905,4
501,10000,1,642,3