前言
我的認(rèn)知里欺冀,fasta格式中“>”
只會(huì)位于行首鞋真。但是我寫腳本用的示例數(shù)據(jù)里出兩行特殊id。這兩個(gè)id中除了行首的“>”运悲,中間還有“>”,造成原腳本不能適用似忧。所以在腳本里加了個(gè)檢查渣叛,檢查是否出了行首還有其它位置有“>”。檢查是檢查了盯捌,但是還沒有解決問題淳衙。于是沒有修改設(shè)定分隔符“$/”
的值,而是改成對(duì)讀入的每行進(jìn)行檢查了饺著。
今天把改后的適用性更廣的代碼發(fā)出來箫攀!腳本有點(diǎn)挫,不過問題不大瓶籽。
使用
跟上一篇代碼一樣
將fasta格式轉(zhuǎn)換為tab分割
perl fa2tab.pl -fa2tab seqs.fa(input) seqs.fa.tsv(output)
將tab分割的文件轉(zhuǎn)換為fasta格式
perl fa2tab.pl -tab2fa seqs.fa.tsv(input) seqs.fa.tsv.fa(output)
注意事項(xiàng):腳本和輸入文件只能放在當(dāng)前目錄匠童。
代碼
#!/usr/bin/env perl
use strict;
my $usage = "Usage:\nperl $0 -fa2tab seqs.fa(input) seqs.fa.tsv(output)\nperl fa2tab.pl -tab2fa seqs.fa.tsv(input) seqs.fa.tsv.fa(output)\n";
my $option = "$ARGV[0]";
die "$usage" unless $option =~ /-fa2tab|-tab2fa/i;#注意優(yōu)先級(jí)埂材;是不是很神奇;
die "$usage" unless @ARGV == 3; #列表上下文
if($option =~ /-fa2tab/i){
open FA,"$ARGV[1]" || die "\nERROR: Couldn't open $ARGV[1] !\n";
my $tmp = "tmp"."$ARGV[2]";
open TMP,'>',$tmp || die "\nERROR: Couldn't open $tmp !\n";
while (<FA>){
if(/\A>/){ #按行首>讀入塑顺;
chomp;
$_ =~ s/^>//;
print TMP "\n$_\t";#第一行會(huì)多一個(gè)空行,所以先建了個(gè)臨時(shí)文件俏险;
}else{
chomp;
print TMP "$_";#此處不添加分隔符严拒,而在id序列行前加換行符;
}
}
close FA;
close TMP;
open TMP,$tmp|| die "\nERROR: Couldn't create $tmp !\n";#開始解決空行問題
open TSV,'>',"$ARGV[2]" || die "\nERROR: Couldn't create $ARGV[2] !\n";
while(<TMP>){
next if /^\s+$/;
print TSV $_;
}
print TSV "\n";#R語言read_delim()讀入數(shù)據(jù)框時(shí)提示“Files must end with a newline”竖独,所以在文件最后放入一個(gè)空行裤唠。
close TMP;
close TSV;
unlink $tmp; #刪除臨時(shí)文件;
}elsif($option =~ /-tab2fa/){
open TSV,"$ARGV[1]" || die "\nERROR: Couldn't open $ARGV[1] !\n";
open FA,'>',"$ARGV[2]"|| die "\nERROR: Couldn't create $ARGV[2] !\n";
my ($id, $seq);
while(<TSV>){
next unless (my ($id,$seq) = /(.*?)\t(.*)/s);
chomp $seq; #對(duì)于這么短的模塊莹痢,這么寫有點(diǎn)多余了种蘸;
print FA ">$id\n$seq\n"; #printf 取格式化輸出控制每行序列數(shù),有興趣的自己改下竞膳。
} #應(yīng)該不用寫else了航瞭,前面已經(jīng)限定了只有這兩種情況才可執(zhí)行;
close FA;
close TSV;
}
總結(jié)
- 新手寫腳本就是在寫bug