社會你明哥,人狠話又多!【小明的碎碎念】與你不見不散!作為一名搞數據的生物狗,咱們是生物狗中代碼寫得最六的,程序員中生物學得最好的——大家沒意見吧,有意見請憋著
跟隨小明的步伐,讓我們開開心心地寫Bug吧
我們的口號是什么?日常寫bug,偶爾寫代碼
下面是正文
目錄
Perl
1.1. Perl中getopt傳參
1.2. Perl中輸出幫助文檔
1.3. 實現實例Shell
2.1. Shell中的getopt傳參
2.2. Shell中輸出幫助文檔
2.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數據分析