黄老之道分享 http://blog.sciencenet.cn/u/jawa 德光上贤,志照正宗!

博文

细节决定成败

已有 2556 次阅读 2023-3-30 13:41 |个人分类:人才培养|系统分类:教学心得

在即将出版的《Perl生物信息学编程》一书中,有这样一个实例练习:用Perl单行命令来确定仅见于skin的多肽、仅见于muscle的多肽以及两者都有的多肽。两个数据文件skin、muscle见GitHub。书中给出的参考答案如下。

1、仅见于皮肤的多肽:

perl -ne 'if(!$#ARGV){$h{$_}=1} else{print if !$h{$_}}' muscle skin >skin.prl

2、仅见于肌肉的多肽:

perl -ne 'if(!$#ARGV){$h{$_}=1} else{print if !$h{$_}}' skin muscle >muscle.prl

3、两者都有的多肽:

perl -ne 'if(!$#ARGV){$h{$_}=1} else{print if $h{$_}}' skin muscle >both.prl

简要解释:通过-e进入单行模式,执行单引号之间的代码;-n选项相当于while (<>) { ... },会依次读取单引号中单行命令后列出的文件。在单行命令模式中,后面提供的文件名作为命令行参数,存入了@ARGV,而#ARGV则返回了@ARGV数组最后一个元素的下标。由于Perl中数组下标默认从0开始,上述命令行有两个文件名作为参数,因此刚开始时,$#ARGV为1(可在BEGIN中检验)。但是,一旦读入第一个文件,相当于$ARGV=shift@ARGV,这时@ARGV里面就只剩下一个文件了,对应的$#ARGV为0了。上述单行命令巧妙地利用了这一点,如第一个单行命令,当读入第一个文件muscle时,$#ARGV为0,那么!$#ARGV就为真,因此muscle中的每一条多肽被记录到哈希%h的键中,对应的值都是1;而读入第二个文件skin时,$#ARGV为-1,因此!$#ARGV为假,执行else语句,skin的每条多肽作为键代入哈希%h检验,如果不存在,!$h{$_}为真,打印的相应多肽就是skin里有但muscle里没有的多肽。余此类推。

现在来验证一下。用最简单的Linux命令来统计只见于skin的多肽数目,comm -23 skin muscle | wc -l,结果为644条;只见于muscle的多肽数目,comm -13 skin muscle | wc -l,结果为679条;二者都有的多肽,comm -12 skin muscle | wc -l,结果为465条。wc -l skin.prl muscle.prl both.prl,结果分别为644、679、464条。啥?二者都有的多肽,为啥Perl单行命令的结果比comm命令的结果少了一条。comm -12 skin muscle > both.comm;comm both.prl both.comm发现,Perl的结果中少了一条多肽YWRSGGM。tail skin muscle发现,在skin中YWRSGGM在倒数第二行,有换行符;在muscle中,YWRSGGM在倒数第一行,没有换行符,因此造成了上述问题。一个快捷的解决方案是给muscle最后一行加个换行符。或者如下,更可确保无误:

perl -nE 'chomp; if(!$#ARGV){$h{$_}=1} else{say if $h{$_}}' skin muscle | wc -l


https://blog.sciencenet.cn/blog-204973-1382368.html

上一篇:半百
下一篇:Perl交互式编程
收藏 IP: 124.128.237.*| 热度|

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-11-21 21:42

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部