我有两个文件: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
谢谢。
答案 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 sort -k1 -u
通过管道将其删除,以删除重复项。 file1.txt
的排序和编号可以通过tee
之类的nl | sort | tee >(join - file2.txt) >(join - file2.txt)
进行优化