![使用 join/awk 在一个表中查找值并将其输出到另一个表中](https://linux22.com/image/184105/%E4%BD%BF%E7%94%A8%20join%2Fawk%20%E5%9C%A8%E4%B8%80%E4%B8%AA%E8%A1%A8%E4%B8%AD%E6%9F%A5%E6%89%BE%E5%80%BC%E5%B9%B6%E5%B0%86%E5%85%B6%E8%BE%93%E5%87%BA%E5%88%B0%E5%8F%A6%E4%B8%80%E4%B8%AA%E8%A1%A8%E4%B8%AD.png)
表 1(制表符分隔):
NC_000001.11 1243 A T 0.14
NC_000005.11 1432 G C 0.0006
NC_000012.12 1284 A T 0.93428
NC_000021.9 9824 T C 0.9
查找表(制表符分隔)- 这实际上很大,gzip 后大约有 6G:
NC_000001.11 1243 rs73647921 A T
NC_000005.11 1432 rs75444 G C
NC_000012.12 1284 rs754723 A T
NC_000021.9 9824 rs865545 T C
我希望输出匹配表 1 的前 4 列,它们对应于查找表的第 1/2/4/5 列;将表1转化为:
MarkerName P-Value
rs73647921 0.14
rs75444 0.0006
rs754723 0.93428
rs865545 0.9
我认为我需要按照以下方式使用 join:
join -t, -a 1 -a 2 -o0,1.5,2.3 -e ' -' file1 file2
但这似乎不起作用。我怎样才能使用 gzip 压缩文件?
答案1
使用 awk (和 bash)你可以写
awk '
BEGIN {FS = OFS = "\t"}
NR == FNR {pvalue[$1,$2,$3,$4] = $5; next}
FNR == 1 {print "MarkerName", "P-Value"}
{ key = $1 SUBSEP $2 SUBSEP $4 SUBSEP $5
sub(/\r$/, "", key)
}
key in pvalue {print $3, pvalue[key]}
' table1.tsv <(zcat lookup.tsv.gz)
awk 使用 SUBSEP 变量来连接数组的逗号分隔索引。
zcat 周围的最后一点语法是 bash流程替代
对于多字段连接条件,join
处理起来可能会很痛苦。如果文件未排序,它也会抱怨。
答案2
你有没有尝试过 .. ?
join -o 2.3,1.5 f1 <(zcat f2.gz )
默认情况下join
使用第一个字段。 (并且-1 x -2 x
相当于-j x
,并且-j 1
相当于" "
)
我假设
- 文件已排序,
- 键仅是第一个字段。
对所有字段进行排序
join -o 2.2,1.2 \
<(awk '{printf "%s %s\n",$1 $2 $3 $4,$5}' f1) \
<(zcat f2.gz| awk '{printf "%s %s\n",$1 $2 $4 $5,$3}' )
在哪里
- 使用两个
awk
管道join
可能不是一个好主意(尽管与awk
唯一的解决方案相比,这可能会节省内存), awk
命令从相关字段构建索引,zcat
用于解压缩,- 这让
0
问题悬而未决。