将file1中的一列与两列中的两列进行比较

时间:2019-11-28 14:29:55

标签: linux bash awk grep cut

我有两个文件:file1.txt和file2.txt

#file1.txt
xap1
NM_121
abc4
xxx0
uvw


#file2.txt
A123  001  xap1    mmmmm
B123       xxx0    nnnnn
C123  003  yyy1    ppppp
D123  004  zzz1    NM_121
E123  005  abc4    llllll
F123       jjjj    www

我想根据文件1的第1列与文件2的第3列和第4列的匹配情况进行以下输出,从文件2获取第2列并打印两者:

#file3.txt
xap1    001
NM_121  004
abc4    005
xxx0    NA
uvw     NA

我使用了以下命令,但不知道如何从file1打印第1列:

grep -w -F -f file1.txt file2.txt | awk '{print $2) > file3.txt

谢谢。

2 个答案:

答案 0 :(得分:0)

$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR==FNR {
    map[$3] = map[$4] = ($2 == "" ? "NA1" : $2)
    next
}
{ print $1, ($1 in map ? map[$1] : "NA2") }

$ awk -f tst.awk file2 file1
xap1    001
NM_121  004
abc4    005
xxx0    NA1

我使用2个不同的NA值来区分$ 1在文件2中存在但条目为空的情况(例如xxx0)与在文件2中不存在$ 1的情况(例如。一些随机字符串,例如foobar

$ cat file1
xap1
NM_121
abc4
xxx0
foobar

$ awk -f tst.awk file2 file1
xap1    001
NM_121  004
abc4    005
xxx0    NA1
foobar  NA2

适合的按摩。

答案 1 :(得分:-1)

以下内容:

{
join -t$'\t' -12 -23 -o1.1,1.2,2.2 <(nl -w1 file1.txt | sort -t$'\t' -k2) <(sort -t$'\t' -k3 file2.txt)
join -t$'\t' -12 -24 -o1.1,1.2,2.2 <(nl -w1 file1.txt | sort -t$'\t' -k2) <(sort -t$'\t' -k4 file2.txt)
} |
sort -t$'\t' -k1 | cut -f2- |
# insert NA is it's missing value
sed 's/\t$/\tNA/'

重新创建以下输入文件:

cat <<EOF >file1.txt
xap1
NM_121
abc4
xxx0
EOF

# used tr to recreate a tab separated file
tr ' ' '\t' <<EOF >file2.txt
A123 001 xap1 mmmmm
B123  xxx0 nnnnn
C123 003 yyy1 ppppp
D123 004 zzz1 NM_121
E123 005 abc4 llllll
EOF

输出:

xap1    001
NM_121  004
abc4    005
xxx0    NA

repl上进行了测试。

要点简要说明:

  • nl -w1 file1.txt | sort -t$'\t' -k2-在file2.txt中对行进行编号,并使用第二个字段进行排序
  • join-联接文件。我们将file1.txt与file2.txt两次连接-首先是在file1.txt和file2.txt中的第一个字段和第三个字段上,然后是在第一个字段和第四个字段上。对于join,输入必须在连接的字段上进行排序。
  • sort -t$'\t' -k1 | cut -f2--file1.txt中的行已编号,因此以后我们可以使用行号对它们进行排序(即恢复file1.txt的原始排序顺序)并删除行号
  • sed 's/\t$/\tNA/'-file2.txt中的字段为空,而OP将输出指定为“ NA”。如果输出中缺少第二列,请在其中插入NA
  • >( ... )process substition
  • 如果一个值与第3个字段和第4个字段都匹配,则它将在输出中出现两次。可以根据需要通过sort -k1 -u通过管道将其删除,以删除重复项。

file1.txt的排序和编号可以通过tee之类的nl | sort | tee >(join - file2.txt) >(join - file2.txt)进行优化