将多个grep变量合并到一个按列的文件中

时间:2018-06-26 08:24:39

标签: bash count grep

我有一些grep表达式,它们计算与字符串匹配的行数,每个表达式用于一组具有不同扩展名的文件:

Nreads_ini=$(grep -c '^>' $WDIR/*_R1.trim.contigs.fasta)
Nreads_align=$(grep -c '^>' $WDIR/*_R1.trim.contigs.good.unique.align)
Nreads_preclust=$(grep -c '^>' $WDIR/*_R1.trim.contigs.good.unique.filter.unique.precluster.fasta)
Nreads_final=$(grep -c '^>' $WDIR/*_R1.trim.contigs.good.unique.filter.unique.precluster.pick.fasta)

每一个抓取都会输出样本名称和出现次数,如下所示。

第一个:

PATH/V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT_R1.trim.contigs.fasta:13175
PATH/V3_F357_N_V4_R805_1_A2_bach2_GAGTGATCGT_R1.trim.contigs.fasta:14801
PATH/V3_F357_N_V4_R805_1_A3_bach3_TGAGCGTGCT_R1.trim.contigs.fasta:13475
PATH/V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG_R1.trim.contigs.fasta:13424
PATH/V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA_R1.trim.contigs.fasta:12053

第二个:

PATH/V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT_R1.trim.contigs.good.unique.align:12589
PATH/V3_F357_N_V4_R805_1_A2_bach2_GAGTGATCGT_R1.trim.contigs.good.unique.align:13934
PATH/V3_F357_N_V4_R805_1_A3_bach3_TGAGCGTGCT_R1.trim.contigs.good.unique.align:12981
PATH/V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG_R1.trim.contigs.good.unique.align:12896
PATH/V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA_R1.trim.contigs.good.unique.align:11617

以此类推。我需要使用这些数字grep输出作为样本名称为键列的列来创建一个.txt文件。样本名称是文件名中“ _R1”之前的一部分(V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA,V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG ...):

Sample                                   | Nreads_ini | Nreads_align  |
-----------------------------------------------------------------------
V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT  | 13175      | 12589         | 
V3_F357_N_V4_R805_1_A2_bach2_GAGTGATCGT  | 14801      | 13934         | 
V3_F357_N_V4_R805_1_A3_bach3_TGAGCGTGCT  | 13475      | 12981         | 
V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG  | 13424      | 12896         |
V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA  | 12053      | 11617         |

有什么主意吗?有没有更简单的解决方案来解决我的问题? 谢谢!

3 个答案:

答案 0 :(得分:1)

在此答案中,变量名缩写为inialign

首先,我们从grep的输出中提取样本名称并计数。由于我们必须多次执行此操作,因此我们定义了函数

e() { sed -E 's,^.*/(.*)_R1.*:(.*)$,\1\t\2,'; }

然后将提取的数据合并到一个文件中。具有相同样本名称的行将被合并。

join -t $'\t' <(e <<< "$ini") <(e <<< "$align")

现在,我们几乎达到了预期的输出。我们只需要添加标题并为表格绘制线即可。

join ... | column -to " | " -N Sample,ini,align

这将打印

Sample                                  | ini   | align
V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT | 13175 | 12589
V3_F357_N_V4_R805_1_A2_bach2_GAGTGATCGT | 14801 | 13934
V3_F357_N_V4_R805_1_A3_bach3_TGAGCGTGCT | 13475 | 12981
V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG | 13424 | 12896
V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA | 12053 | 11617

在标题留出后添加一条水平线,作为读者的练习:)

此方法也适用于两个以上的数字列。 join-N部分必须扩展。 join只能处理两个文件,要求我们使用笨拙的解决方法...

e() { sed -E 's,^.*/(.*)_R1.*:(.*)$,\1\t\2,'; }
join -t $'\t' <(e <<< "$var1") <(e <<< "$var2") |
join -t $'\t' - <(e <<< "$var3") | ... | join -t $'\t' - <(e <<< "$varN") |
column -to " | " -N Sample,Col1,Col2,...,ColN

...因此可以更加轻松地添加另一个帮助器功能

e() { sed -E 's,^.*/(.*)_R1.*:(.*)$,\1\t\2,'; }
j2() { join -t $'\t' <(e <<< "$1") <(e <<< "$2"); }
j() { join -t $'\t' - <(e <<< "$1"); }
j2 "$var1" "$var2" | j "$var3" | ... | j "$varN" |
column -to " | " -N Sample,Col1,Col2,...,ColN

或者,如果所有输入都包含相同顺序的相同样本,则join可以用一个paste命令代替。

答案 1 :(得分:0)

能否请您尝试以下操作,如果有帮助,请告诉我。

awk --re-interval -F"[/.:]"  '
BEGIN{
  print "Sample                                   | Nreads_ini | Nreads_align  |"
}
FNR==NR{
  match($2,/.*[A-Z]{10}/);
  array[substr($2,RSTART,RLENGTH)]=$NF;
  next
}
match($2,/.*[A-Z]{10}/) && (substr($2,RSTART,RLENGTH) in array){
  print substr($2,RSTART,RLENGTH),array[substr($2,RSTART,RLENGTH)],$NF
}
' OFS=" | "  first_one  second_one | column -t

输出如下。

Sample                                   |  Nreads_ini  |  Nreads_align  |
V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT  |  13175       |  12589
V3_F357_N_V4_R805_1_A2_bach2_GAGTGATCGT  |  14801       |  13934
V3_F357_N_V4_R805_1_A3_bach3_TGAGCGTGCT  |  13475       |  12981
V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG  |  13424       |  12896
V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA  |  12053       |  11617

答案 2 :(得分:0)

假设您的文件包含要解析的数据:

$ cat file1
PATH/V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT_R1.trim.contigs.fasta:13175
PATH/V3_F357_N_V4_R805_1_A2_bach2_GAGTGATCGT_R1.trim.contigs.fasta:14801
PATH/V3_F357_N_V4_R805_1_A3_bach3_TGAGCGTGCT_R1.trim.contigs.fasta:13475
PATH/V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG_R1.trim.contigs.fasta:13424
PATH/V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA_R1.trim.contigs.fasta:12053
$ cat file2
PATH/V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT_R1.trim.contigs.good.unique.align:12589
PATH/V3_F357_N_V4_R805_1_A2_bach2_GAGTGATCGT_R1.trim.contigs.good.unique.align:13934
PATH/V3_F357_N_V4_R805_1_A3_bach3_TGAGCGTGCT_R1.trim.contigs.good.unique.align:12981
PATH/V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG_R1.trim.contigs.good.unique.align:12896
PATH/V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA_R1.trim.contigs.good.unique.align:11617
$ cat file3 # This is a copy of file2 but could be different
PATH/V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT_R1.trim.contigs.good.unique.align:12589
PATH/V3_F357_N_V4_R805_1_A2_bach2_GAGTGATCGT_R1.trim.contigs.good.unique.align:13934
PATH/V3_F357_N_V4_R805_1_A3_bach3_TGAGCGTGCT_R1.trim.contigs.good.unique.align:12981
PATH/V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG_R1.trim.contigs.good.unique.align:12896
PATH/V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA_R1.trim.contigs.good.unique.align:11617

如果有诸如V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT之类的密钥,则可以使用awk:

$ awk -F'[/.:]' '
    BEGINFILE{
      col[FILENAME]
    }
    { 
       row[$2]
       a[FILENAME,$2]=$NF
       next
    }
   END{
      for(i in row) { 
        printf "%s ",substr(i,1,length(i)-3)
        for(j in col) 
          printf "%s ",a[j SUBSEP i]; printf "\n" 
      }
  }' file1 file2 file3
V3_F357_N_V4_R805_1_A4_bach4_TGTGTGCATG 13424 12896 12896
V3_F357_N_V4_R805_1_A1_bach1_GTATCGTCGT 13175 12589 12589
V3_F357_N_V4_R805_1_A3_bach3_TGAGCGTGCT 13475 12981 12981
V3_F357_N_V4_R805_1_A2_bach2_GAGTGATCGT 14801 13934 13934
V3_F357_N_V4_R805_1_A5_bach5_TGTGCTCGCA 12053 11617 11617

此awk脚本填充3个数组colrowa,分别存储列名(文件名),行内容和所有文件的值。

END语句通过遍历所有行和列来打印数组a的内容。

如果您需要餐桌装饰,请使用此:

{ printf "Sample Nreads_ini Nreads_align Nreads_align \n"; awk -F'[/.:]' 'BEGINFILE{col[FILENAME]}{row[$2];a[FILENAME,$2]=$NF;next}END{for(i in row) { printf "%s ",substr(i,1,length(i)-3); for(j in col) printf "%s ",a[j SUBSEP i]; printf "\n" }}' file1 file2 file3; } | column -t  -s' ' -o ' | '