一般来说,面对日常处理的一些小任务,直接用 sed
,grep
之类的就可以搞定,更复杂一点的就会考虑 awk
或者用一些现成的轮子,要是 awk
搞不定我就只好用 Python 了。但有些时候,我仅仅只是想写一个一次性脚本,不想打开编辑器写所谓 格式优美 的 Python 语句呢?(正如写 Perl 一样随性)
其实在 Python 中也可以使用单行命令,直接用 python -c
即可,虽然这与 Python 之禅中所说的 Readability counts 相悖,但信手拈来,随便用用还是挺方便的。
-c cmd : program passed in as string (terminates option list)
terminates option list 表示
-c
之后的其它选项不起作用,为终极选项。
例如:
python -c "print('Hello World')"
Hello World
-c
之后,要用双引号将命令包起来,import
以;
结尾,命令用[]
括起来,多行命令用多个[]
。
python -c "import os,time;[print(i) for i in os.listdir()];[print(time.time())]"
一些比较复杂的命令复杂的命令必须要用[]括起来,否则会报错。
举个实际的例子,比如在生物信息学编程实战一文中第三题 ,hg19 基因组序列的一些探究,jimmy 老师用 Perl 单行命令做了这道题:
perl -alne '{if(/^>/){$chr=$_}else{ $A_count{$chr}+=($_=~tr/Aa//); $T_count{$chr}+=($_=~tr/Tt//);$C_count{$chr}+=($_=~tr/Cc//); $G_count{$chr}+=($_=~tr/Gg//); $N_count{$chr}+=($_=~tr/Nn//); }}END{print "$_ $A_count{$_} $T_count{$_} $C_count{$_} $G_count{$_} $N_count{$_}" foreach sort keys %N_count}' test.fa
示例数据:
>chr_1ATCGTCGaaAATGAANccNNttGTAAGGTCTNAAccAAttGggG>chr_2ATCGAATGATCGANNNGccTAAGGTCTNAAAAGG>chr_3ATCGTCGANNNGTAATggGAAGGTCTNAAAAGG>chr_4ATCGTCaaaGANNAATGANGgggTA
结果如下:
>chr_1 13 10 7 10 4>chr_2 11 6 5 8 4>chr_3 10 6 3 10 4>chr_4 9 4 2 7 3
这题用 Python 单行命令也可以写:
cat test.fa | python -c "import sys;from Bio import SeqIO;[print(line.id,line.seq.count('A'),line.seq.count('T'),line.seq.count('C'),line.seq.count('G')) for line in SeqIO.parse(sys.stdin,'fasta')]"
这里我就用了 Biopython 来解析 fasta 格式,所以 Python 的优势就在于有众多现成的模块可以调用,减少了代码量。
再举个例子,比如一行代码转换 genbank 为 fasta :
cat sequence.gb | python -c "import sys;from Bio import SeqIO;SeqIO.write(SeqIO.parse(sys.stdin, 'genbank'),sys.stdout,'fasta')" > sequence.fasta
关于更多 Biopython 的内容可以参见我之前的笔记:
•我的Python笔记·BioPython(一)•我的Python笔记·BioPython(二)•用 BioPython 做一些酷酷的事情(一)•用 BioPython 做一些酷酷的事情(二)
其他例子
•算术:
python -c "print(3.0/2)"
•导入模块并输出结果:
python -c "import math;print(math.sin(1))"
•使用循环输出 1-10:
python -c "for i in range(1,11):print(i)"
•使用多个循环(注意格式):
python -c "for i, j in ((i,j) for i in range (1,11) for j in range(1,11)): print(i, j)"
•实现类似 grep
的功能,输出正则匹配的行:
echo hey | python -c "import sys,re;[sys.stdout.write(line) for line in sys.stdin if re.search('he.', line)]"
•实现类似 sed
的功能,使用正则表达式替换并输出结果:
echo hallo | python -c "import sys,re;[sys.stdout.write(re.sub('h[au]llo', 'hello', line)) for line in sys.stdin]"
•删除前两个字符:
python -c "import sys;[sys.stdout.write(' '.join(line.split(' ')[2:])) for line in sys.stdin]" < input.txt
除了使用 -c
之外,Python 还可以使用 -m
参数直接使用模块
-m mod : run library module as a script (terminates option list)
•使用 calendar 模块,输出今年的日历:
python -m calendar
•开启文件分享:
python -m http.server 8000
执行后,在本机打开 http://localhost:8000
,或者在局域网内的其它机器上打开 http://本机ip:8000
,就能访问到执行目录下的文件。
•生成 HTML 格式官方帮助文档:
python -m pydoc -p 9000
•安装 module:
python -m pip install xxx
这种写法相比于 pip install xxx
,在存在多个 Python 版本的环境中,可以精确地控制三方库的安装位置。
•创建、查看和提取 zip 格式压缩包:•-l
显示 zip 格式压缩包中的文件列表•-c
创建 zip 格式压缩包•-e
提取 zip 格式压缩包•-t
验证文件是一个有效的 zip 格式压缩包
python -m zipfile -c test.zip tmp1.txt tmp2.txtpython -m zipfile -e test.zip target-dir/python -m zipfile -l test.zip
引用链接
[1]
https://en.wikibooks.org/wiki/Python_Programming/Command-line_one-liners
[2]
Python 中 -m 的典型用法、原理解析与发展演变
生信技能树目前已经公开了三个生信知识库,记得来关注哦~
每周文献分享
https://www.yuque.com/biotrainee/weeklypaper
肿瘤外显子分析指南
https://www.yuque.com/biotrainee/wes
生物统计从理论到实践
https://www.yuque.com/biotrainee/biostat
友情宣传
强烈建议你推荐给身边的博士后以及年轻生物学PI,多一点数据认知,让他们的科研上一个台阶:
•生信技能树的2019年终总结,你的生物信息学成长宝藏•2020学习主旋律,B站74小时免费教学视频为你领路•全国巡讲全球听(买一得五),你的生物信息学入门课