我有两个文件,如下所示
file1
name|address office
AK|Victoria Street
BK|Admond Street
DK|Business Street
file2
name|address home
AK|Nilofer Villa
ck|Bluewaters
bk|Homingo Apartment
命令或代码行应该比较两个文件的第一列并将列合并为name|address office|address home
,并在不匹配的地方替换NA,文件的内容可能很大。完整输出应如下
file3
name|address office|address home
AK|Victoria Street |Nilofer Villa
BK|Admond Street|Homingo Apartment
DK|Business Street|NA
CK|NA|Bluewaters
这是我到目前为止所尝试的内容:
awk -F '|' 'NR==FNR{c[$1]++;next};c[$1] > 0' file1 file2
但上面的代码行没有合并,只是根据列名生成输出差异。这个案例太敏感了
name|address home
AK|Nilofer Villa
请帮助,也检查了几个问题,但没有解决我的目的。
答案 0 :(得分:4)
您可以使用join
命令执行此操作:
$ join -a 1 -a 2 -e NA -o '0,1.2,2.2' -t '|' -i <(sort f1) <(sort f2)
AK|Victoria Street|Nilofer Villa
BK|Admond Street|Homingo Apartment
ck|NA|Bluewaters
DK|Business Street|NA
name|address office|address home
其中:
-a 1
和-a 2
包含来自任一文件的未加入的行。-e
和-o
一起展示“NA”字段。手册页未提及此内容,但要使用-e
,您必须指定-o
。我们只按以下顺序显示字段:连接列,第一个文件的第二列,第二个文件的第二列。-t
设置分隔符当然我们还必须在使用join之前对文件进行排序(这是必需的),因此我们使用进程替换。如果你的shell没有,你可以使用临时文件。
答案 1 :(得分:2)
$ cat tst.awk
BEGIN { FS=OFS="|" }
{
name = (FNR>1 ? toupper($1) : $1)
if (!seen[name]++) {
names[++numNames] = name
vals[name,1] = vals[name,2] = "NA"
}
vals[name,ARGIND] = $2
}
END {
for (nameNr=1; nameNr<=numNames; nameNr++) {
name = names[nameNr]
print name, vals[name,1], vals[name,2]
}
}
$ awk -f tst.awk file1 file2
name|address office|address home
AK|Victoria Street|Nilofer Villa
BK|Admond Street|Homingo Apartment
DK|Business Street|NA
CK|NA|Bluewaters
以上使用GNU awk进行ARGIND,其他awk只是在脚本开头添加FNR==1{ARGIND++}
。