将多个shell脚本集成到一个脚本中

时间:2014-04-26 14:04:28

标签: linux bash shell awk

我想将一些简短的脚本集成到一个脚本中,我可以从命令行更新输入文件的参数。我正在浏览22个文件并计算$5!="1"的行数。 这是输入文件的示例头: 目前,我有以下3个短脚本:

CHROM POS   N_ALLELES N_CHR {FREQ}
2   45895   2   162 0.993827    0.00617284
2   45953   2   162 0.993827    0.00617284
2   264985  2   162 1   0
2   272051  2   162 0.944444    0.0555556

1)计数行(保存为wcYRI.sh):$5!="1"{sum++}END{print sum}

2)应用linecount(保存为check-annos.sh):awk -f wcYRI.sh ~/folder$1/file$1

3)对22个文件应用linecount,对输出求和:

    for i in {1..22}; 
    do sh check-annos.sh $i; done 
    | awk '{sum+=$1}END{print sum}'

它相对简单,但有时脚本1对于看起来像这样的数据文件会更长一点:

Chr Start   End Ref Alt Func.refGene    Gene.refGene    ExonicFunc.refGene  AAChange.refGene    LJB2_SIFT   LJB2_PolyPhen2_HDIV LJB2_PP2_HDIV_Pred  LJB2_PolyPhen2_HVAR LJB2_PolyPhen2_HVAR_Pred    LJB2_LRT    LJB2_LRT_Pred   LJB2_MutationTaster LJB2_MutationTaster_Pred    LJB_MutationAssessor    LJB_MutationAssessor_Pred   LJB2_FATHMM LJB2_GERP++ LJB2_PhyloP LJB2_SiPhy
16  101593  101593  C   T   exonic  POLR3K  nonsynonymous SNV   POLR3K:NM_016310:exon2:c.G164A:p.G55E   0.000000    0.997   D   0.913   D   0.000000    D   0.999989    D   2.205   medium  0.99    5.3 2.477000    17.524

...我正在使用像这样的awk文件(执行数组匹配)作为输入-f到上面的脚本2:

NR==FNR{
    arr[$1$2];next
}   
    $1$2 in arr && $0~/exonic/&&/nonsynonymous SNV/{nonsyn++};
    $1$2 in arr && $0~/exonic/&&/synonymous SNV/ && $0!~/nonsynonymous/{syn++}
END{
    print nonsyn,"nonsyn YRI","\t",syn,"YRI syn"
}

我的目标是将此过程进一步整合,因此我不需要进入脚本2并每次都更改~/folder$1/file$1 - 我希望能够使用{ {1}}作为命令行的输入。但是,当我尝试在命令行的for循环中使用这样的东西时,它并不接受~/folder$1/file$1在将$1构建到被调用的单独脚本中时的方式$1 for-do-done循环(如脚本3 - 脚本3将采用脚本2,但我只能将脚本2的内容明确地输入到for循环中作为参数)。

我实际上并不那么担心有一个单独的AWK文件来处理行解析,主要的是让我烦恼的是我正在为每个文件夹/文件集修改脚本2,我希望能够做到这一点从命令行,以便脚本知道我何时告诉它~/folder$1/file$1,循环通过数字1-22我可以为此过程保存一个通用脚本,因为我有许多文件夹/文件组合要查看。

任何建议都赞赏缩短管道,但具体来说命令行参数问题让我烦恼不已!

1 个答案:

答案 0 :(得分:2)

如果我正确理解了问题,我会看到两种方法来处理它。如果路径格式一致(即数字始终出现两次,在相同位置),则可以使脚本接受路径的各个部分作为两个不同的参数。该脚本如下所示:

#!/bin/bash
folderPrefix="$1"
filePrefix="$2"

for num in {1..22}; do
    awk -f wcYRI.sh "$folderPrefix$num/$filePrefix$num"
done | 
    awk '{sum+=$1}END{print sum}'

...然后你用./scriptname ~/folder file运行它。或者,如果您需要能够更灵活地定义文件夹/文件路径格式,您可以执行以下操作:

#!/bin/bash

for num in {1..22}; do
    eval "awk -f wcYRI.sh $1"
done | 
    awk '{sum+=$1}END{print sum}'

...然后使用./scriptname '~/folder$num/file$num'运行它。请注意,此处需要使用单引号,以便$var引用不会展开,直到eval强制它们为止。

BTW,文件wcYRI.sh是一个awk脚本,而不是shell脚本,因此我建议更改其文件扩展名以防止混淆。实际上,执行此操作(对于shell和awk脚本)的首选方法是在脚本中添加一个shebang行作为第一行(请参阅上面的示例;对于awk脚本,它将是#!/usr/bin/awk -f),然后使脚本可执行,然后只用./scriptname运行它,让shebang负责指定解释器(sh,bash,awk -f,等等)。