awk 用于过滤两个文件的内容

awk 用于过滤两个文件的内容
$ file1.txt    
12345,865221,APPLE,ZZ,QQ,DD,GG,APPLE-FRUIT
12346,865222,MANGO,ZZ,QQ,DD,GG,MANGO-FRUIT
12347,865222,GRAPE,ZZ,QQ,DD,GG,GRAPE-FRUIT

$file2.txt
APPLE-FRUIT,10KG
MANGO-FRUIT,12KG

我有两个文件,如上所述。我需要创建一个新文件,如下所示。

$Output
12345,865221,APPLE,ZZ,QQ,DD,GG,APPLE-FRUIT,10KG
12346,865222,MANGO,ZZ,QQ,DD,GG,MANGO-FRUIT,12KG
12347,865222,GRAPE,ZZ,QQ,DD,GG,GRAPE-FRUIT

我研究出的一种方法是使用 while 循环。我读取了 file2 的每一行,并将第一列与 file1 的第 8 列进行比较。这样我就可以获得所需的输出。我正在寻找一个简单的 awk 命令来实现相同的目的。

答案1

使用join

join -t, -a 1 -1 8 -2 1 file1.txt file2.txt

使用awk

将第一个文件的内容保存在一个数组中,并以相应的索引为键,并在处理第二个文件时调用它:

awk -F "," '
    FILENAME=="file1.txt"{row[$8]=$0}
    FILENAME=="file2.txt"{OFS=","; print row[$1],$2}
' file*.txt

对于您的新要求:

awk -F "," '
    FILENAME=="file1.txt"{row[$8]=$0}
    FILENAME=="file2.txt"{row[$1]=row[$1]","$2}
    END{ for (i in row) print row[i] }
' file*.txt

请注意,这将改变排序


使用csvsql

这也是一个很好的用例csvsql,特别是当您的文本字段包含引号且分隔符位于引号内时,上述解决方案将失败:

csvsql -H \
  --query  "select file1.*, file2.b from file1 left join file2 on file1.h == file2.a" \
  file*.txt

答案2

我首先循环遍历较小的文件:

awk -F, -v OFS=, '
    NR == FNR    { weight[$1] = $2; next }
    $8 in weight { $(NF+1) = weight[$8] }
    1
' file2.txt file1.txt

相关内容