连接两个 csv + 第一个文件第一列 + 第二个文件第一列并仅获取匹配列数据

连接两个 csv + 第一个文件第一列 + 第二个文件第一列并仅获取匹配列数据

文件1.txt

name
abc
xyz
pqr

文件2.txt

name,addr,id
abc,hj,1
pqr,hj.2
jkd,hj,9
jh,jd,2

输出文件

name,addr,id
abc,hj,1
pqr,hj.2

答案1

使用join

join -t, -o 0,1.2,1.3 <(sort <(tail -n +2 file2)) <(sort <(tail -n +2 file1))
abc,hj,1
pqr,hj,2
  • -t,将输入/输出字段分隔符指定为逗号
  • -o只输出指定字段;0是连接(第一个)字段(可以用1.1或替换2.1);格式是(哪个文件中的X.Y哪个字段。)YX

  • tail -n +2 infile返回除第一行之外的所有行标头线。

  • sort ...对每个输入文件进行排序。

或者与awk

awk -F, 'NR==FNR {!seen[$1]; next} $1 in seen' file1 file2
name,addr,id
abc,hj,1
pqr,hj,2
  • -F,指定输入字段分隔符是逗号
  • NR==FNR;NR将在读取的第一条记录/行上设置为 1awk并递增,直到读取单个输入文件或多个文件的所有记录/行;FNR将在读取的第一条记录/行上设置为 1awk并递增,直到当前输入文件中读取所有记录/行,并将在下一个文件中重置回 1;所以NR==FNR只有当awk正在读取第一个file1输入文件,并且将执行其后续块。它正在创建一个关联的数组,seen用以下行调用文件1作为该数组的索引(如果之前未设置)。

  • $1 in seen:仅在第二个执行file2并检查该文件中的第一列是否与数组中的任何键匹配,seen然后将其打印。

答案2

这将起作用:

grep --color=never -f <(cut -d, -f1 file1.txt | sed 's#.*#^\0,#') file2.txt 

解释:

  • grep -f:从FILE中获取模式,每行一个
  • --color=never(可选)grep从匹配的输出中删除颜色。
  • <([...]) 是根据括号之间的内容创建文件描述符的语法,如下所示:
  • cut -d, -f1 file1.txt将返回 file1.txt 的第一列
  • sed 's#.*#^\0,#'将使第一列读起来就像^column1,为 . 创建正确的模式grep

如果您想排除标题以避免错误(在您的示例中不需要),请使用以下命令:

head -n 1 file2.txt && \
grep --color=never -f <(tail -n +2 file1.txt | cut -d, -f1 | sed 's#.*#^\0,#') file2.txt

两个命令都返回:

name,addr,id
abc,hj,1
pqr,hj.2

相关内容