如何计算匹配条件的数量,如果它们不匹配则返回零值?

时间:2013-12-05 11:07:25

标签: regex unix if-statement grep

我正在尝试计算输入列表中匹配项的数量,该列表包含每行一个术语和一个数据文件,并创建一个输出文件,其中包含匹配(grep'd)项和匹配项的数量以及其中的位置不匹配,返回零值。

输入列表:

+ 5S_rRNA
+ 7SK
+ AC001
+ AC000111.3
+ AC000111.6

data.txt文件:

chr10   101780038   101780209   5S_rRNA
chr10   103578280   103578430   5S_rRNA
chr10   112327234   112327297   5S_rRNA
chr10   120766459   120766601   7SK
chr10   127408228   127408317   7SK
chr10   127511874   127512063   AADAC
chr10   14614140    14614294    AC000111.3

我想创建一个输出文件,其中包含所有不匹配的术语和匹配的术语以及相应的计数,如下所示:

+ 5S_rRNA   3
+ 7SK   2
+ AC001 0
+ AADAC 1
+ AC000111.3    1
+ AC000111.6    0

我可以创建一个包含匹配术语和计数的输出文件但我不知道如果没有匹配则如何获取零值并让它将所有输出打印到单独的文件。 这些是我用来创建匹配术语的代码(感谢perreal和Mark Setchell)

#!/bin/bash
 while read line
do
   line=${line##+ }       # Strip off leading + and space
   n=$(grep "$line" data.txt 2> /dev/null | wc -l)
   if [ $n -gt 0 ]; then
      echo $line 
      echo $n
       fi
 done < input_list.txt > output.txt

cut -d' ' -f2 input.txt | grep -o -f - data.txt | sort | uniq -c | \
  sed 's/\s*\([0-9]*\)\s*\(.*\)/+ \2\t\1/' > output.txt

任何建议都会很棒。谢谢 哈丽特

3 个答案:

答案 0 :(得分:1)

您可以将此简单循环与grep -c

一起使用
while read l; do echo -n "+ $l "; grep -c "$l" file1; done < inputs
+ 5S_rRNA 3
+ 7SK 2
+ AC001 0
+ AC000111.3 1
+ AC000111.6 0

答案 1 :(得分:0)

使用制表符,空格或类似的分隔文件时,请考虑awk。也许这就是你要找的东西。我使用了ternary operator,但如果您发现它们更容易阅读,则可以使用if / else语句。

awk 'FNR==NR { a[$4]++; next } { print "+", $2, $2 in a ? a[$2] : 0 }' data.txt inputlist.txt

结果:

+ 5S_rRNA 3
+ 7SK 2
+ AC001 0
+ AC000111.3 1
+ AC000111.6 0

$2 in a ? a[$2] : 0表示如果第二列在数组中(称为a),则返回该键的值。否则,返回零。 HTH。

答案 2 :(得分:0)

cut -d' ' -f2 input.txt | grep -o -f - data.txt | sort | uniq -c | \
    sed 's/\s*\([0-9]*\)\s*\(.*\)/+ \2 \1/' | \
    join -a 1 -e 0 -j 2 input.txt - -o '1.2 2.3' | \
    sed 's/ /\t/;s/^/+ /'