Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.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
Unix 使用awk计算组的motif实例_Unix_Awk - Fatal编程技术网

Unix 使用awk计算组的motif实例

Unix 使用awk计算组的motif实例,unix,awk,Unix,Awk,我有一个超过20gb的文件(很多行)。这些行看起来像这样: group1 motifA group1 motifD group1 motifD group1 motifRalph group1 motifA group2 motifDenzel group2 motifRodger group2 motifHector group2 motifDenzel group2 motifA group2 motifXYZ group2 motifA group2 motifDenzel group3

我有一个超过20gb的文件(很多行)。这些行看起来像这样:

group1 motifA
group1 motifD
group1 motifD
group1 motifRalph
group1 motifA
group2 motifDenzel
group2 motifRodger
group2 motifHector
group2 motifDenzel
group2 motifA
group2 motifXYZ
group2 motifA
group2 motifDenzel
group3 motifHector
group3 motifRalph
group4 motifA
...
group10389
我想创建一个摘要文件,列出每个组中出现的主题以及出现的次数。例如:

group1 motifA 2
group1 motifD 2
group1 motifRalph 1
group2 motifDenzel 3
group2 motifRodger 1
group2 motifHector 1
但我希望所有的图案都是这样。我知道在awk中,您可以使用count,例如:

awk '{count[$1]++} END

但是,像我描述的那样,如何计算组数呢?非常感谢

你能试试下面的吗。在此处读取输入_文件2次

awk 'FNR==NR{a[$1,$2]++;next} a[$1,$2]{print $0,a[$1,$2];delete a[$1,$2]}' Input_file Input_file
第二种方法:只读取一次输入文件(根据Tiw在注释部分的注释,可能需要花费时间,因为整个输入文件正在加载到内存中)


awk'!a[$1fs$2]+{b[++count]=1ofs$2;}{c[$1fs$2]+}END{for(i=1;i请您尝试以下内容。在此处读取输入文件2次

awk 'FNR==NR{a[$1,$2]++;next} a[$1,$2]{print $0,a[$1,$2];delete a[$1,$2]}' Input_file Input_file
第二种方法:只读取一次输入文件(根据Tiw在注释部分的注释,可能需要花费时间,因为整个输入文件正在加载到内存中)


awk'!a[$1fs$2]+{b[++count]=$1ofs$2;}{c[$1fs$2]+}END{for(i=1;i未使用20Gb文件进行测试,但通常可以使用:

sort inputfile |uniq -c

  2 group1 motifA
  2 group1 motifD
  1 group1 motifRalph
  2 group2 motifA
  3 group2 motifDenzel
  1 group2 motifHector
  1 group2 motifRodger
  1 group2 motifXYZ
  1 group3 motifHector
  1 group3 motifRalph
  1 group4 motifA
  ......

未使用20Gb文件进行测试,但通常可以使用:

sort inputfile |uniq -c

  2 group1 motifA
  2 group1 motifD
  1 group1 motifRalph
  2 group2 motifA
  3 group2 motifDenzel
  1 group2 motifHector
  1 group2 motifRodger
  1 group2 motifXYZ
  1 group3 motifHector
  1 group3 motifRalph
  1 group4 motifA
  ......

如果将您的组分组,这种方法应该最有效

$ awk 'function pr() {for(k in a) print p,k,a[k]} 
       p!=$1 {pr(); delete a; p=$1} 
             {a[$2]++} 
       END   {pr()}' file

group1 motifA 2
group1 motifD 2
group1 motifRalph 1
group2 motifA 2
group2 motifHector 1
group2 motifDenzel 3
group2 motifXYZ 1
group2 motifRodger 1
group3 motifHector 1
group3 motifRalph 1
group4 motifA 1

只扫描文件一次,不需要排序输入,并且在内存中只保留一个组块的唯一字段。

如果您的组被分组,这种方法应该最有效

$ awk 'function pr() {for(k in a) print p,k,a[k]} 
       p!=$1 {pr(); delete a; p=$1} 
             {a[$2]++} 
       END   {pr()}' file

group1 motifA 2
group1 motifD 2
group1 motifRalph 1
group2 motifA 2
group2 motifHector 1
group2 motifDenzel 3
group2 motifXYZ 1
group2 motifRodger 1
group3 motifHector 1
group3 motifRalph 1
group4 motifA 1

只扫描文件一次,不需要排序输入,只在内存中保留一组唯一字段。

您提到您有一个20GB的文件,可能有很多不同的行。在最坏的情况下,每行都是不同的。这意味着您需要20GB的内存才能执行类似操作

awk '{a[$0]++}END{for (i in a) print i, a[i] }'
因此,这种方法并没有真正的帮助。从您的输入来看,您的文件似乎是按第一列排序的。如果是这种情况,以下内容可能会有所帮助:

awk '($1 != key) { for(i in a) print i, a[i]; delete a }
     {a[$0]++; key = $1}
     END { for(i in a) print i, a[i] }' file
但是,这可能不会像预期的那样工作,因为该文件可能只包含一个组,而且您可能需要20GB的内存

最好的方法是使用
sort
uniq
。GNU sort的设计使其能够轻松处理远大于系统内存总量的文件。但是,您可能需要添加两个额外选项:

--temporary directory=tempdir
使用directory
tempdir
存储临时文件,覆盖
TMPDIR
环境变量。如果多次提供此选项,临时文件将存储在所有给定的目录中。如果有I/O绑定的大型排序或合并,则通常可以导入通过使用此选项指定不同磁盘和控制器上的目录来提高性能

可能需要此选项,因为
/tmp
可能无法容纳足够的磁盘空间来进行20GB的数据排序

来源:

为了确定您需要使用哪种方法,我建议:

  • 首先计算每组的总条目数:

    $ cut -d " " -f1 file | uniq -c | sort -n | awk '(NR==1)END{print $0}'
    
    上面的行将打印最小和最大的组(假设您的文件是按组排序的)

  • 获取行的最大长度:

    $ awk { l=length($0); m=m<l?l:m } END {print m}' file
    

    $awk{l=length($0);m=m您提到您有一个20GB的文件,可能有很多不同的行。在最坏的情况下,每行都是不同的。这意味着如果您想执行类似操作,您需要20GB的内存

    awk '{a[$0]++}END{for (i in a) print i, a[i] }'
    
    因此,这种方法并没有真正的帮助。从您的输入来看,您的文件似乎是按第一列排序的。如果是这种情况,以下内容可能会有所帮助:

    awk '($1 != key) { for(i in a) print i, a[i]; delete a }
         {a[$0]++; key = $1}
         END { for(i in a) print i, a[i] }' file
    
    但是,这可能不会像预期的那样工作,因为该文件可能只包含一个组,而且您可能需要20GB的内存

    最好的方法是使用
    sort
    uniq
    。GNU sort的设计使其能够轻松处理远大于系统内存总量的文件。但是,您可能需要添加两个额外选项:

    --temporary directory=tempdir
    使用directory
    tempdir
    存储临时文件,覆盖
    TMPDIR
    环境变量。如果多次提供此选项,临时文件将存储在所有给定的目录中。如果有I/O绑定的大型排序或合并,则通常可以导入通过使用此选项指定不同磁盘和控制器上的目录来提高性能

    可能需要此选项,因为
    /tmp
    可能无法容纳足够的磁盘空间来进行20GB的数据排序

    来源:

    为了确定您需要使用哪种方法,我建议:

  • 首先计算每组的总条目数:

    $ cut -d " " -f1 file | uniq -c | sort -n | awk '(NR==1)END{print $0}'
    
    上面的行将打印最小和最大的组(假设您的文件是按组排序的)

  • 获取行的最大长度:

    $ awk { l=length($0); m=m<l?l:m } END {print m}' file
    
    $awk{l=length($0);m=m您也可以尝试Perl

    $  perl -lane ' $kv{$_}++;END { foreach(keys %kv) { print "$_ $kv{$_}" } } ' steveman.txt
    group3 motifHector 1
    group2 motifXYZ 1
    group2 motifDenzel 3
    group1 motifD 2
    group2 motifA 2
    group1 motifRalph 1
    group3 motifRalph 1
    group1 motifA 2
    group4 motifA 1
    group2 motifRodger 1
    group2 motifHector 1
    $
    
    您也可以尝试Perl

    $  perl -lane ' $kv{$_}++;END { foreach(keys %kv) { print "$_ $kv{$_}" } } ' steveman.txt
    group3 motifHector 1
    group2 motifXYZ 1
    group2 motifDenzel 3
    group1 motifD 2
    group2 motifA 2
    group1 motifRalph 1
    group3 motifRalph 1
    group1 motifA 2
    group4 motifA 1
    group2 motifRodger 1
    group2 motifHector 1
    $
    
    另一种解决方案,使用:

    $datamash-t''groupby 1,2 count 2
    (这假设您的输入文件已经根据这两个字段进行了排序;如果没有添加-s,则不知道如何使用20gig文件)

    另一种解决方案,使用:

    $datamash-t''groupby 1,2 count 2