我有两个要比较的文件。我发现如何根据条件比较列和打印。我的问题在于我必须检查file1中列[2]的值是否位于file2中的值中,该值定义为两列中的范围col [2] col [3]。如果这是真的,那么我应该在我的file1中打印文件2的列[4]。
scaffold1_size11 12
scaffold2_size22 26
scaffold3_size33 67
scaffold1_size11 1 10 Os01
scaffold1_size11 12 20 Os08
scaffold1_size11 29 59 Os07
scaffold2_size22 17 24 Os09
scaffold2_size22 27 38 Os09
scaffold2_size22 39 60 Os10
scaffold2_size22 67 78 Os10
scaffold3_size33 15 27 Os03
scaffold3_size33 29 62 Os08
scaffold3_size33 64 78 Os02
scaffold3_size33 80 98 Os01
scaffold1_size11 12 Os08
scaffold2_size22 26
scaffold3_size33 67 Os02
应该怎么做?
答案 0 :(得分:1)
这是一个执行您想要的shell脚本。它使用awk将file2转换为另一个awk脚本(tmp.awk),后者又过滤file1。
awk '{ a[$1] = a[$1] "$2 >= " $2 " && $2 <= " $3 " ? \"" $4 "\" : "; } END { for (i in a) print "$1 == \"" i "\" { print $0 \"\\t\" (" a[i] "\"\"); }"; }' file2 > tmp.awk
awk -f tmp.awk file1
注意:
uniq
或sort -u
。答案 1 :(得分:0)
awk
中的标准成语使用FNR
(文件记录编号)和NR
(总记录编号)来检测您何时阅读第一个文件。您在数组中读取并保存第一个文件的值,然后在读取第二个文件时使用数组。
在此上下文中,您希望首先阅读file1
,根据第1列($1
)中的值保存记录。这假设file1
(第一个字段)中的键是唯一的。然后,在阅读第二个文件时,
awk 'FNR == NR { val[$1] = $2 }
FNR != NR { if ($1 in val && val[$1] >= $2 && val[$1] <= $3)
print $1, val[$1], $4
}' file1 file2
示例输出:
scaffold1_size11 12 Os08
scaffold2_size22 26 Os09
scaffold3_size33 67 Os02
请注意,这与问题中的示例输出不同,即:
scaffold1_size11 12 Os08
scaffold2_size22 26
scaffold3_size33 67 Os02
我认为这是问题中的拼写错误,因为file2
中的所有行都没有丢失第四列。
您还会看到使用的习语如下:
awk 'FNR == NR { …save…; next }
{ …process… }'
next
在读取第一个文件时跳过第二个代码块。它可能稍微有点效率,但我倾向于喜欢两个倒置条件的明确清晰度。
如果输出中的间距有问题,请使用适当的printf
语句代替print
。