shell执行perl_【编程技巧(一)】在Perl、Shell和Python中传参与输出帮助文档

社会你明哥,人狠话又多!【小明的碎碎念】与你不见不散!作为一名搞数据的生物狗,咱们是生物狗中代码写得最六的,程序员中生物学得最好的——大家没意见吧,有意见请憋着

949364e8a18c101a05a79eaa83bd278e.gif

跟随小明的步伐,让我们开开心心地写Bug吧

2dd450ee7b1245f0d7b50ecae2dec71c.gif

我们的口号是什么?日常写bug,偶尔写代码

ee13242eccc9446edb12c54b146d1fda.gif

下面是正文


目录
  1. Perl
    1.1. Perl中getopt传参
    1.2. Perl中输出帮助文档
    1.3. 实现实例

  2. Shell
    2.1. Shell中的getopt传参
    2.2. Shell中输出帮助文档
    2.3. 实现实例

  3. Python
    3.1. Python中的getopt传参
    3.2. Python中输出帮助文档
    3.3. 实现实例


基于本人对多种编程语言的粗浅了解,不论是哪种编程语言它的参数传递方式主要分为下面两类:

  • 直接传递(以Perl为例进行说明)

在调用脚本时,直接传递参数,如:./script.pl a b c

然后在脚本中用@ARGV变量获取这些参数

  • getopt方法

这种方法是大多数专业程序中都会用到的方法,使用的时候在参数名前加连接符,后面接上参数的实际赋值,例如:-a 1

不过getopt方法的参数解析方式略显复杂,下面会在具体的语言中进行逐一说明

直接传递的传参方式的优点是编写和使用起来很方便,但缺点很明显,参数的顺序是固定的,不能随意改变,每回使用时都需要确定各个参数分别是什么,而且一般采用这种传参方式的人是不会编写帮助文档的,所以一旦忘了只能查看源代码

getopt方法的优点是,传参方式灵活,而且采用这种传参方式的程序员一般都会在程序中添加帮助文档,因此这种传参方式对用户是非常友好的,但是对于程序员来说,则意味着他或她不得不多写好几行代码——所以一个好的程序员头顶凉凉是可以理解的~

以下我们只介绍第二种传参方法

1. Perl

1.1. Perl中getopt传参

Perl中的这个功能需要通过调用Getopt::Long模块实现

use Getopt::Long;

然后使用GetOptions函数承接传递的参数:

my ($var1,$var2,$var3,$var4); # 若使用"use strict"模式,则需要提前定义变量
GetOptions(
    "i:s"=>\$var1,
    "o:s"=>\$var2,
    "n:i"=>\$var3,
    "m:i"=>\$var4
    );

这样,你就可以通过以下的方式进行灵活的Perl脚本参数传递了:

$ perl perlscript.pl -i var1 -o var2 ...
1.2. Perl中输出帮助文档

可以使用POD文档实现在Perl中输出帮助文档,想了解更多关于POD文档的知识,请点 这里

=head1 part1

    doc in part1

=head2 part2

    doc in part2

.
.
.

=cut    # pod文档结束的标志

注意:每个=标签上下必须隔一行,否则就会错误解析。

pod2doc $0可以将程序中的文档打印出来,不过一般用在程序内部,当程序参数设定错误时打印pod文档:

die `pod2doc $0` if (...);
1.3. 实现实例
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use POSIX;

# 帮助文档
=head1 Description

    This script is used to split fasta file, which is too large with thosands of sequence

=head1 Usage

    $0 -i  -o  [-n ] [-m ]
=head1 Parameters
    -i  [str]   Input raw fasta file
    -o  [str]   Output file to which directory
    -n  [int]   Sequence number per file, alternate chose paramerter "-n" or "-m", if set "-n" and "-m" at the same time, only take "-n" parameter
    -m  [int]   Output file number (default:100)
=cut
my ($input,$output_dir,$seq_num,$file_num);
GetOptions("i:s"=>\$input,"o:s"=>\$output_dir,"n:i"=>\$seq_num,"m:i"=>\$file_num
    );die `pod2text $0` if ((!$input) or (!$output_dir));
.
.
.

2. Shell

2.1. Shell中的getopt传参

Shell中的这个功能可以通过getopts函数实现

getopts [option[:]] [DESCPRITION] VARIABLE

option:表示为某个脚本可以使用的选项

":":如果某个选项(option)后面出现了冒号(":"),则表示这个选项后面可以接参数(即一段描述信息DESCPRITION)

VARIABLE:表示将某个选项保存在变量VARIABLE中

while getopts ":a:b:c:" opt
do
    case $opt in
        a)
        echo "参数a的值$OPTARG"
        ;;
        b)
        echo "参数b的值$OPTARG"
        ;;
        c)
        echo "参数c的值$OPTARG"
        ;;
        ?)
        echo "未知参数"
        exit 1;;
    esac
done
2.2. Shell中输出帮助文档

在Shell中编辑一个helpdoc( )的函数即可实现输出帮助文档

helpdoc(){
    cat <Description:

    .
    .
    .

Usage:

    $0 -a  -b  -c  ...Option:
    .
    .
    .
EOF
}

将你想要打印出来的帮助信息写在cat <和EOF之间

之所以使用EOF来编写是因为,这是一种所见即所得的文本编辑形式(这个不好解释,请自行百度)

当你要打印帮助文档时,直接调用执行helpdoc( )函数即可

# 当没有指定参数时,即参数个数为0时,输出帮助文档并退出程序执行
if [ $# = 0 ]
then
    helpdoc()
    exit 1
fi
2.3. 实现实例
helpdoc(){
    cat <Description:

    This shellscript is used to run the pipeline to call snp using GATK4
    - Data merge: merge multi-BAM files coresponding to specified strain
    - Data pre-processing: Mark Duplicates + Base (Quality Score) Recalibration
    - Call variants per-sample
    - Filter Variants: hard-filtering

Usage:

    $0 -S  -R  -k  -i 
Option:
    -S    strain name, if exist character "/", place "/" with "_" (Required)
    -R    the path of bwa index (Required)
    -k    known-sites variants VCF file
    -i    intervals list file,must be sorted (Required)
EOF
}
workdir="/work_dir"# 若无指定任何参数则输出帮助文档if [ $# = 0 ]then
    helpdocexit 1fiwhile getopts "hS:k:R:i:" optdocase $opt in
        h)
            helpdocexit 0
            ;;
        S)
            strain=$OPTARG# 检测输入的strain名是否合格:是否含有非法字符"/"if [[ $strain =~ "/" ]]thenecho "Error in specifing strain name, if exist character \"/\", place \"/\" with \"_\""
                helpdocexit 1fiif [ ! -d $workdir/SAM/$strain ]thenecho "There is no such folder coresponding to $strain"
                helpdocexit 1fi
            ;;
        R)
            index=$OPTARG
            ;;
        k)
            vcf=$OPTARGif [ ! -f $vcf ]thenecho "No such file: $vcf"
                helpdocexit 1fi
            ;;    
        i)
            intervals=$OPTARGif [ ! -f $bed ]thenecho "No such file: $intervals"
                helpdocexit 1fi
            ;;
        ?)echo "Unknown option: $opt"
            helpdocexit 1
            ;;esacdone
.
.
.

3. Python

3.1. Python中的getopt传参

Python中的这种功能需要通过getopt模块实现

import getopt

Python脚本获得成对的参数名和参数值后,会分别把它们保存在一个字典变量中,参数名为key,参数值为value

opts,args = getopt.getopt(argv,"hi:o:t:n:",["ifile=","ofile=","time="])

getopt函数的使用说明:

argv:使用argv过滤掉第一个参数(它是执行脚本的名字,不应算作参数的一部分)

"hi:o:t:n:":使用短格式分析串,当一个选项只是表示开关状态时,即后面不带附加参数时,在分析串中写入选项字符。当选项后面是带一个附加参数时,在分析串中写入选项字符同时后面加一个":" 号

["ifile=","ofile=","time="]:使用长格式分析串列表,长格式串也可以有开关状态,即后面不跟"=" 号。如果跟一个等号则表示后面还应有一个参数

然后通过条件判断的方法对参数进行解析:

for opt,arg in opts:
    if opt in ("-h","--help"):
        print(helpdoc)
        sys.exit()
    elif opt in ("-i","--ifile"):
        infile = arg
    elif opt in ("-t","--time"):
        sleep_time = int(arg)
    .
    .
    .
3.2. Python中输出帮助文档

在Python中创建一个字符串变量helpdoc即可实现输出帮助文档

helpdoc = '''
Description
    ...
Usage
    python pyscript.py -i/--ifile  -o/--ofile  -t/--time  ...
Parameters
    -h/--help
        Print helpdoc
    -i/--ifile
        Input file, including only one column with sampleId
    -o/--ofile
        Output file, including two columns, the 1st column is sampleId, the 2nd column is attribute information
    -t/--time
        Time for interval (seconds, default 5s)
    ...
'''

在需要时将这个变量打印出来即可:

try:
    opts,args = getopt.getopt(argv,"hi:o:t:n:",["ifile=","ofile=","time="])
    if len(opts) == 0:
        print("Options Error!\n\n"+helpdoc)
        sys.exit(2)
except getopt.GetoptError:
    print("Options Error!\n\n"+helpdoc)
    sys.exit(2)
3.3. 实现实例
import getopt

.
.
.

if __name__ == '__main__':
    ...
    helpdoc = '''
Description
    This script is used to grab SRA sample attributes information based on SampleId
Usage
    python webspider_ncbiBiosample.py -i/--ifile  -o/--ofile  -t/--time  -n/--requests-number 
Parameters
    -h/--help
        Print helpdoc
    -i/--ifile
        Input file, including only one column with sampleId
    -o/--ofile
        Output file, including two columns, the 1st column is sampleId, the 2nd column is attribute information
    -t/--time
        Time for interval (seconds, default 5s)
    -n/--requests-number
        Setting the requests number between interval (default 10)
'''

    # 获取命令行参数
    try:
        opts,args = getopt.getopt(argv,"hi:o:t:n:",["ifile=","ofile=","time="])
        if len(opts) == 0:
            print("Options Error!\n\n"+helpdoc)
            sys.exit(2)
    except getopt.GetoptError:
        print("Options Error!\n\n"+helpdoc)
        sys.exit(2)

    # 设置参数
    for opt,arg in opts:
        if opt in ("-h","--help"):
            print(helpdoc)
            sys.exit()
        elif opt in ("-i","--ifile"):
            infile = arg
        elif opt in ("-o","--ofile"):
            outfile = arg
            # 若指定的输出文件已经存在,让用户决定覆盖该文件,还是直接退出程序
            if os.path.exists(outfile):
                keyin = input("The output file you specified exists, rewrite it?([y]/n: ")
                if keyin in ("y","Y",""):
                    os.remove(outfile)
                elif keyin in ("n","N"):
                    print("The output file existed!\n")
                    sys.exit(2)
                else:
                    print("Input error!\n")
                    sys.exit(2)
        elif opt in ("-t","--time"):
            sleep_time = int(arg)
        elif opt in ("-n","--requests-number"):
            requestNum = int(arg)

    .
    .
    .

参考资料:

(1) 小明github笔记:Perl进阶笔记

https://github.com/Ming-Lian/Bioinformatics-skills/blob/master/Perl%E8%BF%9B%E9%98%B6%E7%AC%94%E8%AE%B0.md

(2) 小明github笔记:实用小脚本

https://github.com/Ming-Lian/Bioinformatics-skills/blob/master/%E5%AE%9E%E7%94%A8%E5%B0%8F%E8%84%9A%E6%9C%AC.md

(3) 小明github笔记:Linux (Raspbian) 操作进阶——Shell编程

https://github.com/Ming-Lian/Hello-RaspberryPi/blob/master/Linux%E6%93%8D%E4%BD%9C%E8%BF%9B%E9%98%B6.md#shell-programing

(4) Python 命令行参数和getopt模块详解

https://www.cnblogs.com/kex1n/p/5975722.html


【小明的碎碎念】系列往期精彩文章:

(1)三代测序入门:技术原理与技术特点

(2)三代测序入门:PacBio数据分析

d3a673b96b8807bf675f53e82b942f2a.png

85aa0572e1b3d6cc6477768c60422baa.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值