Csv 使用AWK基于多列合并两个文件

Csv 使用AWK基于多列合并两个文件,csv,awk,Csv,Awk,我有两个CSV文件,带有(分号) 作为分隔符,我 需要基于上的三列进行合并 每个文件都使用AWK。关键列 它们不是连续的。我的想法是 从文件B中选择两列并打印它们 在文件A中的所有其他列之后 文件A(键位于A1、A3和A5中): 文件B(B1、B2、B4中的键): 将产生: A1;A2;A3;A4;A5;; K1;D1;K2;D2;K3;D9;D0 K4;D3;K5;D4;K6;DA;DB K7;D5;K8;D6;K9;; K1;D7;K2;D8;K3;D9;D0 我在SO(例如和)和其他地方

我有两个CSV文件,带有(分号) 作为分隔符,我 需要基于上的三列进行合并 每个文件都使用AWK。关键列 它们不是连续的。我的想法是 从文件B中选择两列并打印它们 在文件A中的所有其他列之后

文件A(键位于A1、A3和A5中):

文件B(B1、B2、B4中的键):

将产生:

A1;A2;A3;A4;A5;;
K1;D1;K2;D2;K3;D9;D0
K4;D3;K5;D4;K6;DA;DB
K7;D5;K8;D6;K9;;
K1;D7;K2;D8;K3;D9;D0
我在SO(例如和)和其他地方找到了几个示例,但我无法将它们转换为我的需要,因为它们没有被很好地记录下来,以至于像我这样的AWK n00b能够真正理解它们是如何工作的

最接近我的是:

awk -F \; -v OFS=\; 'FNR==NR{c[$1]=$3 FS $5;next}{ print $0, c[$1]}' B A
但它仍然从输出行1和4中删除了一个分号或一列:

A1;A2;A3;A4;A5;
K1;D1;K2;D2;K3;D9;D0
K4;D3;K5;D4;K6;DA;DB
K7;D5;K8;D6;K9;
K1;D7;K2;D8;K3;D9;D0

如何声明要使用哪些列进行比较?显然,现在它只使用第一列进行比较。

join-j1-a1-t';'<代码>连接-j1-a1-t';'<代码>连接-j1-a1-t';'<代码>连接-j1-a1-t';' 不确定我是否正确理解了需求,但这给出了给定输入的预期输出:

join -j1 -a1 -t';' <(cut -d';' -f 1,3,5 A | sed -e 's/;//g' | paste -d';' - A | sort ) <(cut -d';' -f 1,2,4 B | sed -e 's/;//g' | paste -d';' - B | sort ) | cut -d';' -f2,3,4,5,6,9,11

#the commands on new lines for readability only
#join command, print all of file A, even if unmatching
join -j1 -a1 -t';'
#input from file A
<(cut -d';' -f 1,3,5 A | sed -e 's/;//g' | paste -d';' - A | sort )
#input from file B
<(cut -d';' -f 1,2,4 B | sed -e 's/;//g' | paste -d';' - B | sort )
#selecting the columns
| cut -d';' -f2,3,4,5,6,9,11
awk -F \; -v OFS=\; 'FNR==NR{c[$1]=$3 FS $5;next}{ print $0, $1 in c ? c[$1] : ";"}' B A
A1;A2;A3;A4;A5;;
K1;D1;K2;D2;K3;D9;D0
K4;D3;K5;D4;K6;DA;DB
K7;D5;K8;D6;K9;;
K1;D7;K2;D8;K3;D9;D0
根据问题中的代码,我将打印语句从

print $0, c[$1]


不确定我是否正确理解了需求,但这给出了给定输入的预期输出:

awk -F \; -v OFS=\; 'FNR==NR{c[$1]=$3 FS $5;next}{ print $0, $1 in c ? c[$1] : ";"}' B A
A1;A2;A3;A4;A5;;
K1;D1;K2;D2;K3;D9;D0
K4;D3;K5;D4;K6;DA;DB
K7;D5;K8;D6;K9;;
K1;D7;K2;D8;K3;D9;D0
根据问题中的代码,我将打印语句从

print $0, c[$1]


不确定我是否正确理解了需求,但这给出了给定输入的预期输出:

awk -F \; -v OFS=\; 'FNR==NR{c[$1]=$3 FS $5;next}{ print $0, $1 in c ? c[$1] : ";"}' B A
A1;A2;A3;A4;A5;;
K1;D1;K2;D2;K3;D9;D0
K4;D3;K5;D4;K6;DA;DB
K7;D5;K8;D6;K9;;
K1;D7;K2;D8;K3;D9;D0
根据问题中的代码,我将打印语句从

print $0, c[$1]


不确定我是否正确理解了需求,但这给出了给定输入的预期输出:

awk -F \; -v OFS=\; 'FNR==NR{c[$1]=$3 FS $5;next}{ print $0, $1 in c ? c[$1] : ";"}' B A
A1;A2;A3;A4;A5;;
K1;D1;K2;D2;K3;D9;D0
K4;D3;K5;D4;K6;DA;DB
K7;D5;K8;D6;K9;;
K1;D7;K2;D8;K3;D9;D0
根据问题中的代码,我将打印语句从

print $0, c[$1]


这将在没有额外
的情况下打印在不匹配的行上。你必须先提供B文件

 awk 'BEGIN {
          OFS=FS=";"
      } 

      FNR==NR {
          key[$1 FS $2 FS $4]=$3 OFS $5
      } 

      FNR!=NR {
          c=$1 FS $3 FS $5; 
          if(c in key) 
               print $0,key[c]; 
          else 
               print
      }'  fileB fileA

如果需要额外的分隔符,请将最后一个
print
更改为
print$0 of s of s

这将在没有额外
的情况下打印在不匹配的行上。你必须先提供B文件

 awk 'BEGIN {
          OFS=FS=";"
      } 

      FNR==NR {
          key[$1 FS $2 FS $4]=$3 OFS $5
      } 

      FNR!=NR {
          c=$1 FS $3 FS $5; 
          if(c in key) 
               print $0,key[c]; 
          else 
               print
      }'  fileB fileA

如果需要额外的分隔符,请将最后一个
print
更改为
print$0 of s of s

这将在没有额外
的情况下打印在不匹配的行上。你必须先提供B文件

 awk 'BEGIN {
          OFS=FS=";"
      } 

      FNR==NR {
          key[$1 FS $2 FS $4]=$3 OFS $5
      } 

      FNR!=NR {
          c=$1 FS $3 FS $5; 
          if(c in key) 
               print $0,key[c]; 
          else 
               print
      }'  fileB fileA

如果需要额外的分隔符,请将最后一个
print
更改为
print$0 of s of s

这将在没有额外
的情况下打印在不匹配的行上。你必须先提供B文件

 awk 'BEGIN {
          OFS=FS=";"
      } 

      FNR==NR {
          key[$1 FS $2 FS $4]=$3 OFS $5
      } 

      FNR!=NR {
          c=$1 FS $3 FS $5; 
          if(c in key) 
               print $0,key[c]; 
          else 
               print
      }'  fileB fileA


如果您需要额外的分隔符,请将最后一个
print
更改为
print$0 of s of s

在输入、所需输出、应如何比较(以及哪些)列方面,您能否更具体一些?文件A中的哪些列必须与文件B中的哪些列匹配,以及哪些列应该在输出中打印?如果不清楚,很抱歉,但是文件A和B应该合并比较列(A1、A3、A5)到(B1、B2、B4)。至于输出,所有列都应该从A输出,而“非键”列(B3和B5)应该从B输出。你是对的,输出示例在这方面有点不清楚。我尝试在代码块中使用粗体,但在代码块中不起作用。如果文件被排序,会出现问题吗?考虑一下,即创建一个从A1、A3、A5到B1、B2、B4的虚拟比较字段,不带分隔符,并基于这些字段进行联接。您的示例代码仅使用$1作为键,而不是其他两个字段。您能否在输入方面更具体一些,所需输出,应如何比较(和哪些)列?文件A中的哪些列必须与文件B中的哪些列匹配,以及哪些列应该在输出中打印?如果不清楚,很抱歉,但是文件A和B应该合并比较列(A1、A3、A5)到(B1、B2、B4)。至于输出,所有列都应该从A输出,而“非键”列(B3和B5)应该从B输出。你是对的,输出示例在这方面有点不清楚。我尝试在代码块中使用粗体,但在代码块中不起作用。如果文件被排序,会出现问题吗?考虑一下,即创建一个从A1、A3、A5到B1、B2、B4的虚拟比较字段,不带分隔符,并基于这些字段进行联接。您的示例代码仅使用$1作为键,而不是其他两个字段。您能否在输入方面更具体一些,所需输出,应如何比较(和哪些)列?文件A中的哪些列必须与文件B中的哪些列匹配,以及哪些列应该在输出中打印?如果不清楚,很抱歉,但是文件A和B应该合并比较列(A1、A3、A5)到(B1、B2、B4)。至于输出,所有列都应该从A输出,而“非键”列(B3和B5)应该从B输出。你是对的,输出示例在这方面有点不清楚。我尝试在代码块中使用粗体,但在代码块中不起作用。如果文件被排序,会出现问题吗?考虑一下,即创建一个从A1、A3、A5到B1、B2、B4的虚拟比较字段,不带分隔符,并基于这些字段进行联接。您的示例代码仅使用$1作为键,而不是其他两个字段。您能否在输入方面更具体一些,所需输出,应如何比较(和哪些)列?文件A中的哪些列必须与文件B中的哪些列匹配,以及哪些列应该在输出中打印?如果不清楚,很抱歉,但是文件A和B应该合并比较列(A1、A3、A5)到(B1、B2、B4)。至于输出,所有列都应该从A输出,而“非键”列(B3和B5)应该从B输出。你是对的,输出示例在这方面有点不清楚。我尝试在代码块中使用粗体,但在代码块中不起作用。如果文件被排序,会出现问题吗?考虑一下,例如,创建一个从A1、A3、A5到B1、B2、B4的虚拟比较字段,不带分隔符,并基于这些字段进行联接。您的示例代码仅使用$1作为键,而不是其他两个字段。它排除了所需输出中的第1行和第4行。哦,我跳过了您也需要
A
的不匹配行。已更新,请参见
join
command.note中的
-a1