计算另一个文件中变量的出现次数

计算另一个文件中变量的出现次数

我确实有以下情况:

文件 1 看起来像:

A  
B  
C  

文件2看起来像:

chr1 \t 1234523 \t A  
chr3 \t 1234231 \t A  
chr6 \t 121233 \t A  
chr1 \t 1126685 \t B  
chr1 \t 15834523 \t B  
chr4 \t 12345647 \t C  
chr12 \t 1456523 \t C  

我想得到输出:

A \t 3 
B \t 2  
C \t 2  

我知道我可以这样做

grep A File2 | wc -l

但是,我需要对 File1 中的每一行(700)执行此操作。

我怎样才能自动化呢?

答案1

假设\ts 实际上是制表符,并且出现在同一列上,并且 A 只匹配 A,不匹配 AA。让a为包含 A、B、C 的文件和b您要计算匹配项的文件(您提供的第二个文件)。

  • 首先,您需要仅从 中获取可能的匹配项b,而忽略其他所有内容。这是 的第三列b,所以我们可以使用cutit 来剪切文件的一部分

    切-f 3 b

  • 然后,您需要将其转换为出现次数及其计数的列表:您可以uniq在输出上进行排序并用于对这些次数进行计数cut

    排序|优衣库-c

  • 最后,你这样做是为了全部中的值b,但您只需要来自 的值a。您可以使用join它在公共字段上连接两个不同的文件(在本例中,第一个也是唯一的字段a(似乎默认情况下这样做)和第二个字段(2b,这是第二个文件(-2

    连接 -2 2 a 结果-b

您可以通过几种不同的方式链接它,一种可能的方法是使用来自bash进程替换的命名管道:

join -2 2 a <(cut -f 3 b | sort | uniq -c)

这至少应该比单独的 grep 更好,因为您只处理 b 三次(删除其他列、sortuniq),然后我想连接只会读取每个文件一次,因为它需要对输入进行排序。当然,这依赖于我所做的假设(并且您还必须进行排序a,但这只是<(sort a)代替a之前未排序的情况。

答案2

从示例输入来看,您希望对制表符分隔记录的最后一个字段中的每个不同值进行计数。这是执行此操作的 awk 片段。

awk -F '\t' '
     {++a[$NF]}
     END {for (x in a) {print x "\t" a[x]}}
' File2

答案3

你可以用 while 循环来做到这一点

while read arg < FILE1; do echo -n -e "$arg\t"; grep "$arg" FILE2 | wc -l; done

这将读取 FILE1,并且对于每一行,for 循环都会将字符串存储到变量 $arg 中。

然后它将回显 $arg (-n 表示不在末尾插入行返回 (\n),-e 表示执行转义字符)。

然后它将显示在 FILE2 中找到 $arg 的出现次数。

相关内容