【问题标题】:Merge two files with similar column entries合并具有相似列条目的两个文件
【发布时间】:2012-04-08 21:08:55
【问题描述】:

我有一些文件,其中包含用户名和数据传输速率(以 MB/s 为单位)。这些数据收集了一年,每个月的报告都保存在 12 个不同的文件中。我必须合并所有文件以准备最终报告。

文件如下

Filename1 : January

#User Name           #Data Transferred

A. Paul                       300004
Jason                        600000
Mayur Pandey             40000
Kelly H                       459000
Ryan M                       349000


Filename2 : March 

#User Name           #Data Transferred

Senthl V R                  600000
Mayur Pandey                40000
Kelly H                     459000
Pratap S                    349000
A. Paul                     300004

同样,我还有 10 个文件。我必须将所有这些文件合并到一个文件中,最终输出应如下所示:

Final Report:

#Username     #January      ....     #March ......... #December      #Total

A. Paul        300004                300004            Not available 600008
Pratap S       Not availanble        30000             32000         7899887
Kelly H        459000                459000            459000        3424448274
Mayur Pandey   40000                 400000            400000        242424442
Senthl V R     Not available         600000            34544         53546464
Jason          600000                Not available     3434343       43434355

我需要一个 Perl 脚本来自动执行此操作,而不是使用 Excel 或手动执行。

这些报告每月生成一次,名称未按排序顺序存储。名称存储在最近使用过数据传输工具的用户中。还有一些情况下,用户在特定月份根本没有使用数据传输;在这种情况下,用户名不会出现在月度报告文件中。在这种情况下,我必须在月份名称列中添加 not available

所有字段或列值由 \t TAB 分隔并存储在普通 txt 文件中。

谢谢

【问题讨论】:

  • 我无法为这个要求制定任何逻辑。

标签: linux perl shell unix


【解决方案1】:

这比真正的困难更繁琐。文件名成为输出中的列标题。您可能会将命令行上文件名的顺序视为它们作为输出列出现的顺序;否则,你会积累太多的知识。当您阅读每个文件时,您会将行拆分为名称和编号。您需要一个按名称索引的哈希值,其值将是对哈希值的引用或对数组的引用。

输出相对简单。您决定显示名称的顺序(您的示例输出没有可辨别的顺序),然​​后按该顺序逐步遍历哈希。对于每个条目,您可以打印每列中的值,在缺少条目时发现并在缺少值时打印“不可用”或附近。您可以随时累积该行的总数,同样也可以累积总总数。

您可能希望将数字右对齐,而不是左对齐。

【讨论】:

    【解决方案2】:

    虽然下面的代码在某处不是很聪明,但我认为它可以解决你的问题。

    use warnings;
    my @file_list=("January","February","March","April","May","June","July","August","September","October","November","December");
    my %priorities=(   
        January=>1,
        February=>2,
        March=>3,
        April=>4,
        May=>5,
        June=>6,
        July=>7,
        August=>8,
        September=>9,
        October=>10,
        November=>11,
        December=>12
    );    
    my %report_datas=();    
    foreach my $file_name (@file_list) {
        open FH , "<" , $file_name or die("can not open file");
        $skip_line=0;
        while(<FH>) {
                $skip_line++;
            next until $skip_line>2;    #skip the header(first two lines)
            chomp;
    
            if(/[^\d]+/) {         #get the name
                $name=$&;
                $name=~s/\s+$//;   #strip the empty chars at the end 
            }
            if(/[\d]+/) {        #get the transfer data
                $data=$&;
            }
    
            $month=$file_name;
            $report_datas{$name}{$month}=$data if not exists $report_datas{$name}{$month};  
            $report_datas{$name}{"priority"}=$priorities{$month};              #always store the latest month while we are reading file_name from January to December 
       }
       close FH;
    }
    
    #sort names by the month of using transfer data
    @sorted_names = sort { $report_datas{$a}{"priority"} <=> $report_datas{$b}{"priority"} } keys %report_datas;  
    
    #print result
    printf "%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s%-18s\n\n","#Username","#January","#February","#March","#April","#May","#June","#July","#August","#September","#October","#November","#December","#Total";
    foreach my $name (@sorted_names) {
        my $sum=0;
        printf "%-18s",$name;
        foreach my $month (@file_list) {
            if ( exists $report_datas{$name}{$month}) {
                printf "%-18d",$report_datas{$name}{$month};
            $sum+=$report_datas{$name}{$month};
            } else {
            printf "%-18s","Not available";
            }
        }
    
        print "$sum\n";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-11
      • 1970-01-01
      • 2017-06-24
      • 1970-01-01
      • 2020-05-18
      • 2021-09-24
      • 2021-07-15
      • 1970-01-01
      相关资源
      最近更新 更多