在 bash 脚本中使用 awk 实现 vlookup 功能

Using awk for vlookup functionality in bash script

输入如下:

files1.csv

21|AAAAA|1023
21|BBBBB|1203
21|CCCCC|2533
22|DDDDD|1294
22|EEEEE|1249
22|FFFFF|4129
22A|GGGGG|4121
22A|HHHHH|1284
31B|IIIII|5403
31B|JJJJJ|1249

file2.csv

21|A800
22|B900
22A|C1000
31B|D1000

预期输出:

files3.csv

21|A800|AAAAA|1023
21|A800|BBBBB|1203
21|A800|CCCCC|2533
22|B900|EEEEE|1249
22|B900|FFFFF|4129
22A|C1000|GGGGG|4121
22A|C1000|HHHHH|1284
31B|D1000|IIIII|5403
31B|D1000|JJJJJ|1249

目前正在尝试使用连接,

join -a1 -t '|' -1 1 -2 1 -o 1.1,2.2,1.2,1.3 file1.csv file2.csv > file3.csv

但它发现有些行没有匹配,所以我将我的想法转变为对这两个文件使用最有可能的 vlookup 功能。请帮忙。

谢谢大家

能否请您尝试使用 awk,使用 GNU awk 编写和测试并显示示例。

awk '
BEGIN{
  FS=OFS="|"
}
FNR==NR{
  arr[]=
  next
}
( in arr){
  =( OFS arr[])
}
1
' file2.csv file1.csv

解释:为以上添加详细解释。

awk '                  ##Starting awk program from here.
BEGIN{                 ##Starting BEGIN section from here of this program.
  FS=OFS="|"           ##Setting | as field separator and output field separator.
}
FNR==NR{               ##Checking condition if FNR==NR which will be TRUE when file2.csv is being read.
  arr[]=           ##Creating arr with index of 1st field and value of 2nd field.
  next                 ##next will skip all further statements from here.
}
( in arr){           ##checking condition if  is present in arr then do following.
  =( OFS arr[])  ##Saving current  OFS and value of arr with index of  in .
}
1                      ##1 will print the current line.
' file2.csv file1.csv  ##Mentioning Input_file names here.

我测试了您提供的 join 命令,我认为它在我的机器上产生了预期的输出(FreeBSD 12.2-RELEASE):

21|A800|AAAAA|1023
21|A800|BBBBB|1203
21|A800|CCCCC|2533
22|B900|DDDDD|1294
22|B900|EEEEE|1249
22|B900|FFFFF|4129
22A|C1000|GGGGG|4121
22A|C1000|HHHHH|1284
31B|D1000|IIIII|5403
31B|D1000|JJJJJ|1249

您可能需要先在您打算加入的列上对两个文件进行排序(或者在这种情况下,当您加入第一列时,整行也应该有效),即 join -a1 -t '|' -1 1 -2 1 -o 1.1,2.2,1.2,1.3 <(sort file1.csv) <(sort file2.csv) > file3.csv