awk - 减去两个文件中的两个匹配列后没有输出

awk - no output after subtracting two matching columns in two files

我正在学习awk,我想用它来获取两个文件中两列之间的差异

如果 file_2 column-2 中的条目存在于 file_1 column-4 中,我想从 file_1 column-2

中减去 file_2 column-3

file_1.txt

chrom_1 1000    2000    gene_1
chrom_2 3000    4000    gene_2
chrom_3 5000    6000    gene_3
chrom_4 7000    8000    gene_4

file_2.txt

chrom_1 gene_1  114 252
chrom_9 gene_5  24  183
chrom_2 gene_2  117 269

这是我的代码,但没有输出:

awk -F'\t' 'NR==FNR{key[]=;file1col1[]=;next}  in key {print file1col1[]-}' file_1.txt file_2.txt

你很接近。但是通过存储第 4 个字段的值的基因名称索引 key 将允许您简单地减去 key[] - 以获得结果,例如

awk 'NR==FNR {key[] = ; next}  in key {print key[] - }' file1 file2
886
2883

(注意:没有gene_5所以key[gene_5]被当成0。测试 in key条件第二条规则仅当基因存在于 key)

时才执行

写下规则

有时将脚本的规则写出来比尝试从脚本中制作一个 1-liner 更有帮助。这允许更好的可读性。例如:

awk '
  NR==FNR {                 # Rule1 conditioned by NR==FNR (file_1)
    key[] =             # Store value from field 2 indexed by field 4
    next                    # Skip to next record
  }
   in key {               # Rule2 conditioned by  in key (file_2)
    print key[] -       # Output value from file_1 - field 3
  }
' file_1.txt file_2.txt

进一步说明

awk 将从文件中读取每一行输入(记录),并将按照规则出现的顺序将每个规则应用于记录。在这里,当记录号等于文件记录号时(仅对 file_1 为真),应用第一条规则,然后 next 命令告诉 awk 跳过其他所有内容并去读取下一条记录。

规则 2 以 in key 为条件,它测试文件 2 中的基因名称是否作为索引存在于 key 中。 (value in array 测试不会在数组中创建新元素——这是该测试的一个有用的好处)。如果基因名称存在于 file_1 填充的 key 数组中,则从 file_2 中的字段 3 中减去该值并输出差值。

学习 awk 时最好的参考资料之一是 Tje GNU Awk User's Guide。它为 awk 提供了极好的参考,任何仅 gawk 的功能都清楚地标有 '#'