终端窗口和txt文件中的输出是否不同?

时间:2018-11-16 09:05:36

标签: perl hashref perl-hash

我正在尝试通过Perl合并两个文件。

到目前为止的代码:

 my $hash_ref;  
 open (my $I_fh, "<", "File1.txt") or die $!;

 my $line = <$I_fh>;
 while ($line = <$I_fh>) {
 chomp $line;
 my @cols = split ("\t", $line);
 my $key = $cols[1];
 $hash_ref -> {$key} = \@cols;
 }
 close $I_fh;

 open (my $O_fh, "<", "File2.txt") or die $!;
 while ($line = <$O_fh>) {
 chomp $line;
 my @cols = split ("\t", $line);
 my $key = shift (@cols);
 push (@{$hash_ref -> {$key}}, @cols);

 }
 close $O_fh;


 open (my $out, ">", "merged.txt") or die $!;

 foreach my $key (sort keys %$hash_ref) {

 my $row = join ("\t", @{$hash_ref -> {$key}});

print $out "$key\t$row\n";
 }
close $out;

我正在使用打印或转储功能检查每个步骤。在终端窗口中,一切都很好。但是,在我的输出文件(合并的txt)中,格式已更改。我想通过添加更多列而不是添加更多行来合并两个文件。如何修复代码?

  File 1.txt:  
  Index    Name    Column1   Column2  
   1        A1                  AB      
   2        A2                  CD   
   3        B1                  EF    
   4        B2                  GH   


    File 2.txt:   
    Name  Type  
     A1     1  
     A2     1   
     B1     2   
     B2     1    

   Merged file:  

   A1   1   AB    
        1     
   A2   2   CD  
        1      
   B1   3   EF  
        2      
   B2   4   GH   
        1      

Wanted file:  
Name  Type  Column2  

  A1   1   AB    
  A2   1   CD   
  B1   2   EF   
  B2   1   GH

1 个答案:

答案 0 :(得分:1)

假设文件是​​根据名称列进行排序的,这要归功于join(1)程序:

$ join --header -t $'\t' -o 2.1,2.2,1.4 -1 2 -2 1 file1.tsv file2.tsv
Name    Type    Column2
A1  1   AB
A2  1   CD
B1  2   EF
B2  1   GH

--header选项是GNU扩展,它排除了两个文件的第一行之间的联接,而将它们视为列标题。 -t设置列分隔符,-o控制输出中包含哪些列(FILE.COLUMN指定符列表),-1-2选择用于合并两个文件。

如果未对它们进行排序,或者如果您对perl进行了设置,则您的代码看起来非常接近;除了所有错别字外,您还将打印每一列,而不仅仅是您想要的输出所暗示的。考虑:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw/say/;
use autodie;

my %names;

sub read_file {
  my ($file, $idx) = @_;
  open my $in, "<", $file;
  my $header = <$in>;
  while (<$in>) {
    chomp;
    my @F = split /\t/;
    push @{$names{$F[$idx]}}, \@F;
  }
}

read_file "file1.tsv", 1;
read_file "file2.tsv", 0;

say "Name\tType\tColumn2";
for my $n (sort keys %names) {
  my $row = $names{$n};
  say "$n\t$row->[1][1]\t$row->[0][3]";
}

我还怀疑,当您的操作系统使用Unix样式的行尾时,您的程序可能会在使用Windows样式的行尾的数据文件上运行,从而解释了您的奇怪输出。