shell执行perl_【编程技巧(一)】在Perl、Shell和Python中传参与输出帮助文档
社會(huì)你明哥,人狠話又多!【小明的碎碎念】與你不見不散!作為一名搞數(shù)據(jù)的生物狗,咱們是生物狗中代碼寫得最六的,程序員中生物學(xué)得最好的——大家沒意見吧,有意見請(qǐng)憋著
跟隨小明的步伐,讓我們開開心心地寫B(tài)ug吧
我們的口號(hào)是什么?日常寫bug,偶爾寫代碼
下面是正文
目錄
Perl
1.1. Perl中g(shù)etopt傳參
1.2. Perl中輸出幫助文檔
1.3. 實(shí)現(xiàn)實(shí)例
Shell
2.1. Shell中的getopt傳參
2.2. Shell中輸出幫助文檔
2.3. 實(shí)現(xiàn)實(shí)例
Python
3.1. Python中的getopt傳參
3.2. Python中輸出幫助文檔
3.3. 實(shí)現(xiàn)實(shí)例
基于本人對(duì)多種編程語言的粗淺了解,不論是哪種編程語言它的參數(shù)傳遞方式主要分為下面兩類:
直接傳遞(以Perl為例進(jìn)行說明)
在調(diào)用腳本時(shí),直接傳遞參數(shù),如:./script.pl a b c
然后在腳本中用@ARGV變量獲取這些參數(shù)
getopt方法
這種方法是大多數(shù)專業(yè)程序中都會(huì)用到的方法,使用的時(shí)候在參數(shù)名前加連接符,后面接上參數(shù)的實(shí)際賦值,例如:-a 1
不過getopt方法的參數(shù)解析方式略顯復(fù)雜,下面會(huì)在具體的語言中進(jìn)行逐一說明
直接傳遞的傳參方式的優(yōu)點(diǎn)是編寫和使用起來很方便,但缺點(diǎn)很明顯,參數(shù)的順序是固定的,不能隨意改變,每回使用時(shí)都需要確定各個(gè)參數(shù)分別是什么,而且一般采用這種傳參方式的人是不會(huì)編寫幫助文檔的,所以一旦忘了只能查看源代碼
getopt方法的優(yōu)點(diǎn)是,傳參方式靈活,而且采用這種傳參方式的程序員一般都會(huì)在程序中添加幫助文檔,因此這種傳參方式對(duì)用戶是非常友好的,但是對(duì)于程序員來說,則意味著他或她不得不多寫好幾行代碼——所以一個(gè)好的程序員頭頂涼涼是可以理解的~
以下我們只介紹第二種傳參方法
1. Perl
1.1. Perl中g(shù)etopt傳參
Perl中的這個(gè)功能需要通過調(diào)用Getopt::Long模塊實(shí)現(xiàn)
use?Getopt::Long;然后使用GetOptions函數(shù)承接傳遞的參數(shù):
my?($var1,$var2,$var3,$var4);?#?若使用"use?strict"模式,則需要提前定義變量GetOptions(
????"i:s"=>\$var1,
????"o:s"=>\$var2,
????"n:i"=>\$var3,
????"m:i"=>\$var4
????);
這樣,你就可以通過以下的方式進(jìn)行靈活的Perl腳本參數(shù)傳遞了:
$?perl?perlscript.pl?-i?var1?-o?var2?...1.2. Perl中輸出幫助文檔
可以使用POD文檔實(shí)現(xiàn)在Perl中輸出幫助文檔,想了解更多關(guān)于POD文檔的知識(shí),請(qǐng)點(diǎn) 這里
=head1?part1????doc?in?part1
=head2?part2
????doc?in?part2
.
.
.
=cut????#?pod文檔結(jié)束的標(biāo)志
注意:每個(gè)=標(biāo)簽上下必須隔一行,否則就會(huì)錯(cuò)誤解析。
用pod2doc $0可以將程序中的文檔打印出來,不過一般用在程序內(nèi)部,當(dāng)程序參數(shù)設(shè)定錯(cuò)誤時(shí)打印pod文檔:
die?`pod2doc?$0`?if?(...);1.3. 實(shí)現(xiàn)實(shí)例
#!/usr/bin/perluse?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中的這個(gè)功能可以通過getopts函數(shù)實(shí)現(xiàn)
getopts?[option[:]]?[DESCPRITION]?VARIABLEoption:表示為某個(gè)腳本可以使用的選項(xiàng)
":":如果某個(gè)選項(xiàng)(option)后面出現(xiàn)了冒號(hào)(":"),則表示這個(gè)選項(xiàng)后面可以接參數(shù)(即一段描述信息DESCPRITION)
VARIABLE:表示將某個(gè)選項(xiàng)保存在變量VARIABLE中
while?getopts?":a:b:c:"?optdo
????case?$opt?in
????????a)
????????echo?"參數(shù)a的值$OPTARG"
????????;;
????????b)
????????echo?"參數(shù)b的值$OPTARG"
????????;;
????????c)
????????echo?"參數(shù)c的值$OPTARG"
????????;;
?????????)
????????echo?"未知參數(shù)"
????????exit?1;;
????esac
done
2.2. Shell中輸出幫助文檔
在Shell中編輯一個(gè)helpdoc( )的函數(shù)即可實(shí)現(xiàn)輸出幫助文檔
helpdoc(){????cat?<Description:
????.
????.
????.
Usage:
????$0?-a??-b??-c??...Option:
????.
????.
????.
EOF
}
將你想要打印出來的幫助信息寫在cat <和EOF之間
之所以使用EOF來編寫是因?yàn)?#xff0c;這是一種所見即所得的文本編輯形式(這個(gè)不好解釋,請(qǐng)自行百度)
當(dāng)你要打印幫助文檔時(shí),直接調(diào)用執(zhí)行helpdoc( )函數(shù)即可
#?當(dāng)沒有指定參數(shù)時(shí),即參數(shù)個(gè)數(shù)為0時(shí),輸出幫助文檔并退出程序執(zhí)行if?[?$#?=?0?]
then
????helpdoc()
????exit?1
fi
2.3. 實(shí)現(xiàn)實(shí)例
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"#?若無指定任何參數(shù)則輸出幫助文檔if?[?$#?=?0?]then
????helpdocexit?1fiwhile?getopts?"hS:k:R:i:"?optdocase?$opt?in
????????h)
????????????helpdocexit?0
????????????;;
????????S)
????????????strain=$OPTARG#?檢測(cè)輸入的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模塊實(shí)現(xiàn)
import?getoptPython腳本獲得成對(duì)的參數(shù)名和參數(shù)值后,會(huì)分別把它們保存在一個(gè)字典變量中,參數(shù)名為key,參數(shù)值為value
opts,args?=?getopt.getopt(argv,"hi:o:t:n:",["ifile=","ofile=","time="])getopt函數(shù)的使用說明:
argv:使用argv過濾掉第一個(gè)參數(shù)(它是執(zhí)行腳本的名字,不應(yīng)算作參數(shù)的一部分)
"hi:o:t:n:":使用短格式分析串,當(dāng)一個(gè)選項(xiàng)只是表示開關(guān)狀態(tài)時(shí),即后面不帶附加參數(shù)時(shí),在分析串中寫入選項(xiàng)字符。當(dāng)選項(xiàng)后面是帶一個(gè)附加參數(shù)時(shí),在分析串中寫入選項(xiàng)字符同時(shí)后面加一個(gè)":" 號(hào)
["ifile=","ofile=","time="]:使用長(zhǎng)格式分析串列表,長(zhǎng)格式串也可以有開關(guān)狀態(tài),即后面不跟"=" 號(hào)。如果跟一個(gè)等號(hào)則表示后面還應(yīng)有一個(gè)參數(shù)
然后通過條件判斷的方法對(duì)參數(shù)進(jìn)行解析:
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中創(chuàng)建一個(gè)字符串變量helpdoc即可實(shí)現(xiàn)輸出幫助文檔
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)
????...
'''
在需要時(shí)將這個(gè)變量打印出來即可:
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. 實(shí)現(xiàn)實(shí)例
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)
'''
????#?獲取命令行參數(shù)
????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)
????#?設(shè)置參數(shù)
????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
????????????#?若指定的輸出文件已經(jīng)存在,讓用戶決定覆蓋該文件,還是直接退出程序
????????????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進(jìn)階筆記
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筆記:實(shí)用小腳本
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) 操作進(jìn)階——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 命令行參數(shù)和getopt模塊詳解
https://www.cnblogs.com/kex1n/p/5975722.html
【小明的碎碎念】系列往期精彩文章:
(1)三代測(cè)序入門:技術(shù)原理與技術(shù)特點(diǎn)
(2)三代測(cè)序入門:PacBio數(shù)據(jù)分析
總結(jié)
以上是生活随笔為你收集整理的shell执行perl_【编程技巧(一)】在Perl、Shell和Python中传参与输出帮助文档的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode165. 比较版本号 超
- 下一篇: python基础技巧总结(一)