比较两行

时间:2019-03-29 10:03:33

标签: linux shell unix

  

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

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

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

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

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

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

将文件B(性别)的第七列与文件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

2 个答案:

答案 0 :(得分:0)

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

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

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

  • 读取文件B中的每一行
  • 沿|分割:返回大小均匀的列表
  • 将列表分配给哈希:偶数项将是键,奇数项将是值
  • 打印出哈希的内容
    • 使用文件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

答案 1 :(得分:0)

可以使用小脚本来完成它:

#!/bin/bash

cat fileA | sed 's#^|##' | sed 's#|$##' > fileC
for line in $(cat fileB)
do
  unset output
  for col in $(cat fileA | sed "s#|# #g")
  do
    value=$(echo $line | sed "s#.*$col|\([^|]*\)|*.*#\1#")
    [ "$value" != "$line" ] && output=$output"|"$value || output=$output"|"
  done
    echo $output | sed 's#^|##' | sed 's#|$##' >> fileC
done