我正在尝试计算输入列表中匹配项的数量,该列表包含每行一个术语和一个数据文件,并创建一个输出文件,其中包含匹配(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
任何建议都会很棒。谢谢 哈丽特
答案 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/^/+ /'