包含来自不同文件 Perl 的列的文件

File containing columns from different files Perl

我想合并 2 个文件中的多列。

第一个文件例如:

Name   Age
Bob    22
Carl   19
Daniel 29
Frank  31
Zach   22

第二个文件例如:(DANIEL 没有 GPA 值,所以我们将其留空)

Name   GPA
Bob    3.0
Carl   3.5
Daniel
Frank  2.6
Zach   2.9

我想输出类似

的东西
Name   Age    GPA
Bob    22     3.0
Carl   19     3.5
Daniel 29
Frank  31     2.6
Zach   22     2.9

由于名称相同,我可以使用任一文件的第一列。

这是我目前的代码,但它没有输出任何东西。

unless (open COL1, '<'. $file1) {die "Couldn't open '$file1'\n";}
unless (open COL2, '<'. $file2) {die "Couldn't open '$file2'\n";}

my %feature;
my @files = (scalar <COL1>, scalar <COL2>);

for my $file (@files) {
    open my $infh, '<', $file or die $!;
    while (<$infh>) {
        chomp;
        my ($feature, $value) = split /\s+/, $_;
        push @{$feature{$feature}}, $value;
    }
}
close COL1;
close COL2;
foreach my $k (keys %feature) {
    print "$k @{$feature{$k}}\n";
}

我该如何解决这个问题,以便它从第一个文件中获取第一列和第二列,并将第二个文件中的第二列附加到它上面? (我要的是姓名、年龄、GPA的顺序)

use List::Util qw( max );

my %students;

{
    open(my $fh, '<', $qfn1)
       or die("Can't open \"$qfn1\": $!\n");
    while (<$fh>) {
        my ($name, $age) = split;
        $students{$name}{age} = $age;
    }
}

{
    open(my $fh, '<', $qfn2)
       or die("Can't open \"$qfn2\": $!\n");
    while (<$fh>) {
        my ($name, $gpa) = split;
        $students{$name}{gpa} = $gpa;
    }
}

my $max_name_len = max map length, "Name", keys %students;
my $max_age_len  = max map length, "Age", grep defined, map $_->{age}, values %students;
my $max_gpa_len  = max map length, "GPA", grep defined, map $_->{gpa}, values %students;

printf("%-*s %-*s %-*s\n",
    $max_name_len, "Name",
    $max_age_len,  "Age",
    $max_gpa_len,  "GPA",
);

for my $name (sort keys %students) {
    my $student = $students{$name};
    my $age = $student->{age};
    my $gpa = $student->{gpa};
    printf("%-*s %*s %*s\n",
        $max_name_len, $name,
        $max_age_len,  $age // "",
        $max_gpa_len,  $gpa // "",
    );
}

虽然我喜欢 perl...非 perl shell 一行:

$ join --header -t $'\t' file1.txt file2.txt
Name    Age     GPA
Bob     22      3.0
Carl    19      3.5
Daniel  29
Frank   31      2.6
Zach    22      2.9

(需要 bash、zsh 或另一个理解 $'\t' 文字的 shell,以及 GNU 连接。还假设文件按照您的示例排序。)