Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 计算文本文件中匹配术语的数量?_Perl_Unix_Grep_Match - Fatal编程技术网

Perl 计算文本文件中匹配术语的数量?

Perl 计算文本文件中匹配术语的数量?,perl,unix,grep,match,Perl,Unix,Grep,Match,我试图从一个输入列表中计算匹配项的数量,该列表包含数据文件中每行一个项,并创建一个输出文件,其中包含匹配(grep'd)项和匹配项的数量 input_list.txt如下所示: + 5S_rRNA + 7SK + AADAC + AC000111.3 + AC000111.6 data.txt文件: chr10 101780038 101780209 5S_rRNA chr10 103578280 103578430 5S_rRNA chr10 112327234

我试图从一个输入列表中计算匹配项的数量,该列表包含数据文件中每行一个项,并创建一个输出文件,其中包含匹配(grep'd)项和匹配项的数量

input_list.txt如下所示:

+ 5S_rRNA
+ 7SK
+ AADAC
+ 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
chr10   14695964    14696146    AC000111.6
我想创建一个输出文件(output.txt),其中包含匹配的术语及其相应的计数

+ 5S_rRNA   3
+ 7SK   2
+ AADAC 1
+ AC000111.3    1
+ AC000111.6    1
到目前为止,我已经使用下面的脚本生成了一个包含所有匹配项的列表,但是所有提供匹配项计数的尝试都没有成功

    exec < input_list.txt
    while read line
    do
                grep -w data.txt | awk '{print $0}'| sort| uniq  >> grep_output.txt
    done
exec>grep|u output.txt
完成
我尝试了
grep-o-w | wc-l和grep-w data.txt | wc-l
等,但我无法确定如何生成包含匹配项及其相应计数的输出列表


任何建议都很好

您可以将input.txt中的单词变灰,并使用uniq获取计数:

cut -d' ' -f2 input.txt | grep -o -f - data.txt | sort | uniq -c
给出:

您还可以添加另一个sed以获得格式化输出:

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


awk
可以很好地实现这一点:

$ awk 'NR==FNR {vals[$2]=$2}
       $4 in vals {count[$4]++}
       END {for (i in count) print i, count[i]}' input_list data.txt
AC000111.3 1
AC000111.6 1
5S_rRNA 3
AADAC 1
7SK 2
解释
vals[]
存储
输入列表
文件的第二个字段。然后,它检查第二个文件
data.txt
的第四个字段是否在任何行中,并统计
count[]
数组中的出现次数。最后,它在
END{}
块中打印输出

通过
n
(数字)
r
(反向)和
k2
(第二列)选项,您可以获得排序数据:

$ awk 'NR==FNR {vals[$2]=$2}
       $4 in vals {count[$4]++}
       END {for (i in count) print i, count[i]}' input_list data.txt | sort -rnk2
5S_rRNA 3
7SK 2
AC000111.6 1
AC000111.3 1
AADAC 1

你可以这样做——这可能就是你自己的目标。它基本上使用“wc-l”统计匹配数,如果大于零,则输出搜索字符串和匹配数:

#!/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 $n
   fi
done < input_list.txt
#/bin/bash
读行时
做
line=${line###+}#去掉前导+和空格
n=$(grep“$line”data.txt 2>/dev/null | wc-l)
如果[$n-gt 0];然后
echo$line$n
fi
完成
您也可以在perl中使用哈希来实现这一点:

#!/usr/bin/perl
use warnings;
use strict; 

open my $list, '<', 'in.txt' or die "$!";
open my $input, '<', 'in.2.txt' or die "$!";

my @split;
my (%data, %hash, %exists);
while(<$input>){
    chomp;
    @split = split(/\s+/);
    my ($info) = $split[3];
    $data{$info}++;
}

while (<$list>){
    chomp;
    my @split = split(/\+ /);
    my ($match) = $split[1];
    $hash{$match} = 1;
}

my $count = 0;
for my $compare (keys %hash){
    if (exists $data{$compare} ){
        $exists{$compare} = $data{$compare};        
        }
 }

foreach my $c (keys %exists){
    print "+ $c: $exists{$c}\n"
}

+1.然而,对于所需的格式,我宁愿使用
paste
。类似于:
paste-d''input.txt此外,
sort
管道在这里可能没有用。愚蠢的问题是,如何将输出打印到单独的文件中?谢谢两个回音。。。“echo$line”然后在下一行“echo$n”仍在打印到屏幕上将“>yourOutputFile”添加到最后一行的末尾。
#!/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 $n
   fi
done < input_list.txt
perl -lane '$s{ $F[3] }++ END{ print "+ $_ $s{$_}" for sort keys %s }' data.txt
#!/usr/bin/perl
use warnings;
use strict; 

open my $list, '<', 'in.txt' or die "$!";
open my $input, '<', 'in.2.txt' or die "$!";

my @split;
my (%data, %hash, %exists);
while(<$input>){
    chomp;
    @split = split(/\s+/);
    my ($info) = $split[3];
    $data{$info}++;
}

while (<$list>){
    chomp;
    my @split = split(/\+ /);
    my ($match) = $split[1];
    $hash{$match} = 1;
}

my $count = 0;
for my $compare (keys %hash){
    if (exists $data{$compare} ){
        $exists{$compare} = $data{$compare};        
        }
 }

foreach my $c (keys %exists){
    print "+ $c: $exists{$c}\n"
}
+ 5S_rRNA: 3
+ AADAC: 1
+ 7SK: 2
+ AC000111.6: 1
+ AC000111.3: 1