首页 > 解决方案 > 比较两行

问题描述

将文件 B(名称)的第一列与文件 A 的第一列进行比较

  • 如果匹配选择第二列值(道森)
  • 如果不插入空格

将文件 B(年龄)的第三列与文件 A 的第二列进行比较。

  • 如果匹配,则选择第四列值 (21)
  • 如果不插入空格

将文件 B(部门)的第五列与文件 A 的第三列进行比较

  • 如果匹配选择第六列值
  • 如果不插入空格

比较文件 B(Sex) 的第七列和文件 A 的第四列。

  • 如果匹配,则选择第四列值(男)
  • 如果不插入空格

归档 A 数据

Name|Age|Department|Sex|

文件 B 数据

Name|Dawson|Age|21|Sex|Male
Name|Deepak|Age|22|Department|EEE|Sex|Male

预期输出 - 文件 C

Name|Age|Department|Sex
Dawson|21||Male
Deepak|22|EEE|Male

我在下面尝试过,但它只是取出偶数列。

awk 'BEGIN{FS=OFS="|"} {for(i=2;i<=NF;i+=2){val=(val?val OFS:"") $i};print val;val=""}' File_B.txt

标签: linuxshellunix

解决方案


查看我看到的输入和输出数据

  • 文件 A 是一个键列表
  • 文件 B 是键 + 值组合的列表
  • 输出应该有每个键的列
    • 如果文件 B 中的一行没有键,则该列应为空

这可以通过散列、映射、字典、...(选择您喜欢的语言的数据结构)轻松解决。这是在 Perl 中使用哈希的解决方案:

  • 从文件 B 中读取每一行
  • split together |:返回一个偶数大小的列表
  • 将列表分配给哈希:偶数条目将是键,奇数条目将是值
  • 打印出哈希的内容
    • 使用文件 A 中的键列表
    • 如果键不存在插入一个空字符串
    • 加入列|以生成行字符串
#!/usr/bin/perl
use warnings;
use strict;
use autodie;

die "usage: $0 <headers> <data>\n"
    if @ARGV < 2;

open(my $ifh, '<', $ARGV[0]);
chomp(my $headers = <$ifh>);
close($ifh);

my @headers = split(/\|/, $headers);

open($ifh, '<', $ARGV[1]);
print "$headers\n";
while (<$ifh>) {
    chomp;
    my %row = split(/\|/);
    print join('|',
               map { $row{$_} // '' } @headers
          ), "\n";
}
close($ifh);

exit 0;

测试运行:

$ cat fileA.txt 
Name|Age|Department|Sex|

$ cat fileB.txt 
Name|Dawson|Age|21|Sex|Male
Name|Deepak|Age|22|Department|EEE|Sex|Male

$ perl dummy.pl fileA.txt fileB.txt
Name|Age|Department|Sex|
Dawson|21||Male
Deepak|22|EEE|Male

推荐阅读