grep、awk、sed、打印 file1 和 file2 中的第 2 列第 3 列匹配

grep、awk、sed、打印 file1 和 file2 中的第 2 列第 3 列匹配

编辑:我想将 file1.txt 的第 1,2 列与 file2.txt 的 1,3 列进行匹配,并打印 file2.txt 的匹配行

文件1.txt:

scaffold1   57482
scaffold1   63114
scaffold1   63118
scaffold1   63129
scaffold1   63139
scaffold1   63279
scaffold1   63294
scaffold2   65015
scaffold2   77268
scaffold2   77335

文件2.txt:

scaffold1   381 382 T/A +
scaffold1   384 385 T/A,G   +
scaffold1   385 386 G/C +
scaffold1   445 446 C/T +
scaffold1   57481   57482   T/A +
scaffold1   63113   63114   T/A,G   +
scaffold1   63128   63129   G/C +
scaffold2   65014   65015   G/A +
scaffold2   77267   77268   G/A +
scaffold2   77334   77335   C/T +

输出.txt:

scaffold1   57481   57482   T/A +
scaffold1   63113   63114   T/A,G   +
scaffold1   63128   63129   G/C +
scaffold2   65014   65015   G/A +
scaffold2   77267   77268   G/A +
scaffold2   77334   77335   C/T +

答案1

解决方案awk

$ awk 'NR==FNR{a[$1$2]++;next}{if($1$3 in a){print}}' file1 file2 
scaffold1   57481   57482   T/A +
scaffold1   63113   63114   T/A,G   +
scaffold1   63128   63129   G/C +
scaffold2   65014   65015   G/A +
scaffold2   77267   77268   G/A +
scaffold2   77334   77335   C/T +

NR是当前行号和FNR当前文件的当前行号。仅当读取第一个文件时,两者才相等。因此第一个块只会在读取第一个文件时执行,因此第一个文件的第一个和第二个字段保存在数组中a。然后,当处理第二个文件时,仅当第一个和第三个字段存在于 中时,我们才打印其行a,因此仅当它存在于第一个文件中时。

答案2

如果您的示例数据可以概括,则可以做出几个假设:

  • 您只需将文件 1 的第 2 列与文件 2 的第 3 列匹配
  • 输入文件已按以上列排序

如果这些假设是合理的,那么以下join命令将起作用:

join -1 2 -2 3 -o "1.1,2.2,2.3,2.4,2.5" file1.txt file2.txt > output.txt

输出是:

scaffold1 57481 57482 T/A +
scaffold1 63113 63114 T/A,G +
scaffold1 63128 63129 G/C +
scaffold2 65014 65015 G/A +
scaffold2 77267 77268 G/A +
scaffold2 77334 77335 C/T +

或者,如果这些不是有效的假设,那么我们可以awk稍微重新排列列(特别是组合文件 1 的 1,2 列和文件 2 的 1,3 列),然后sort(根据 的要求join)。然后join将匹配组合的列。

join -o "1.2,2.2,2.3,2.4,2.5" <( awk '$1=$1"_"$2" "$1' file1.txt | sort ) <( awk '$1=$1"_"$3' file2.txt | sort )

答案3

尝试使用“cut”来捕获所需的字段,例如:

cut -d$"\t" -f2 file1.txt | sort | > file1_col2.txt

用户 cuonglm 对使用 awk 比较文件并打印匹配项有很好的概述:

比较两个文件中的匹配行并存储阳性结果

相关内容