【问题标题】:how can I pass a value through command line如何通过命令行传递值
【发布时间】:2019-04-13 12:25:21
【问题描述】:

我有一个数据保存在 .txt 中,如下所示

>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RNDDDDTSVCLGTRQCSWFAGCTNRTWNSSAVPLIGLPNTQDYKWVDRNSGLTWSGNDTCLYSCQNQTKGLLYQLFRNLFCSYGLTEAHGKWRCADASITNDKGHDGHRTPTWWLTGSNLTLSVNNSGLFFLCGNGVYKGFPPKWSGRCGLGYLVPSLTRYLTLNASQITNLRSFIHKVTPHR
>sp|P13674|P4HA1_HUMAN Prolyl 4-hydroxylase subunit alpha-1 OS=Homo sapiens OX=9606 GN=P4HA1 PE=1 SV=2
VECCPNCRGTGMQIRIHQIGPGMVQQIQSVCMECQGHGERISPKDRCKSCNGRKIVREKKILEVHIDKGMKDGQKITFHGEGDQEPGLEPGDIIIVLDQKDHAVFTRRGEDLFMCMDIQLVEALCGFQKPISTLDNRTIVITSHPGQIVKHGDIKCVLNEGMPIYRRPYEKGRLIIEFKVNFPENGFLSPDKLSLLEKLLPERKEVEE
>sp|Q7Z4N8|P4HA3_HUMAN Prolyl 4-hydroxylase subunit alpha-3 OS=Homo sapiens OX=9606 GN=P4HA3 PE=1 SV=1
MTEQMTLRGTLKGHNGWVTQIATTPQFPDMILSASRDKTIIMWKLTRDETNYGIPQRALRGHSHFVSDVVISSDGQFALSGSWDGTLRLWDLTTGTTTRRFVGHTKDVLSVAFSSDNRQIVSGSRDKTIKLWNTLGVCKYTVQDESHSEWVSCVRFSPNSSNPIIVSCGWDKLVKVWNLANCKLK
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606 GN=TP53 PE=1 SV=4
IQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQL
>sp|P10144|GRAB_HUMAN Granzyme B OS=Homo sapiens OX=9606 GN=GZMB PE=1 SV=2
MQPILLLLAFLLLPRADAGEIIGGHEAKPHSRPYMAYLMIWDQKSLKRCGGFLIRDDFVLTAAHCWGSSINVTLGAHNIKEQEPTQQFIPVKRPIPHPAYNPKNFSNDIMLLQLERKAKRTRAVQPLRLPSNKAQVKPGQTCSVAGWGQTAPLGKHSHTLQEVKMTVQEDRKCES
>sp|Q9UHX1|PUF60_HUMAN Poly(U)-binding-splicing factor PUF60 OS=Homo sapiens OX=9606 GN=PUF60 PE=1 SV=1
MGKDYYQTLGLARGASDEEIKRAYRRQALRYHPDKNKEPGAEEKFKEIAEAYDVLSDPRKREIFDRYGEEGLKGSGPSGGSGGGANGTSFSYTFHGDPHAMFAEFFGGRNPFDTFFGQRNGEEGMDIDDPFSGFPMGMGGFTNVNFGRSRSAQEPARKKQDPPVTHDLRVSLEEIYSGCTKKMKISHK
>sp|Q06416|P5F1B_HUMAN Putative POU domain, class 5, transcription factor 1B OS=Homo sapiens OX=9606 GN=POU5F1B PE=5 SV=2
IVVKGHSTCLSEGALSPDGTVLATASHDGYVKFWQIYIEGQDEPRCLHEWKPHDGRPLSCLLFCDNHKKQDPDVPFWRFLITGADQNRELKMWCTVSWTCLQTIRFSPDIFSSVSVPPSLKVCLDLSAEYLILSDVQRKVLYVMELLQNQEEGHACFSSISEFLLTHPVLSFGIQVVSRCRLRHTEVLPAEEENDSLGADGTHGAGAMESAAGVLIKLFCVHTKALQDVQIRFQPQLNPDVVAPLPTHTAHEDFTFGESRPELGSEGLGSAAHGSQPDLRRIVELPAPADFLSLSSETKPKLMTPDAFMTPSASLQQITASPSSSSSGSSSSSSSSSSSLTAVSAMSSTSAVDPSLTRPPEELTLSPKLQLDGSLTMSSSGSLQASPRGLLPGLLPAPADKLTPKGPGQVPTATSALSLELQEVEP
>sp|O14683|P5I11_HUMAN Tumor protein p53-inducible protein 11 OS=Homo sapiens OX=9606 GN=TP53I11 PE=1 SV=2
MIHNYMEHLERTKLHQLSGSDQLESTAHSRIRKERPISLGIFPLPAGDGLLTPDAQKGGETPGSEQWKFQELSQPRSHTSLKVSNSPEPQKAVEQEDELSDVSQGGSKATTPASTANSDVATIPTDTPLKEENEGFVKVTDAPNKSEISKHIEVQVAQETRNVSTGSAENEEKSEVQAIIESTPELDMDKDLSGYKGSSTPTKGIENKAFDRNTESLFEELSSAGSGLIGDVDEGADLLGMGREVENLILENTQLLETKNALNIVKNDLIAKVDELTCEKDVLQGELEAVKQAKLKLEEKNRELEEELRKARAEAEDARQKAKDDDDSDIPTAQRKRFTRVEMARVLMERNQYKERLMELQEAVRWTEMIRASRENPAMQEKKRSSIWQFFSRLFSSSSNTTKKPEPPVNLKYNAPTSHVTPSVK

我正在尝试将每个部分尽可能多地分成 10 个区域。

例如,以 > 开头的行保持不变。变成了这样

>sp|Q96A73|P33MX_HUMAN Putative monooxygenase p33MONOX OS=Homo sapiens OX=9606 GN=KIAA1191 PE=1 SV=1
RNDDDDTSVC
NDDDDTSVCL
DDDDTSVCLG
DDDTSVCLGT
.
.
.
.

所以我可以轻松地将数据拆分为尽可能多的数据,例如我想使用以下第 10 节。但是,我不想在算法中设置要拆分的字母数。我希望能够选择我想要的任何数字。我正在尝试使用 Getopt::Std 谁能帮我找到一种方法吗?

比如我想这样运行代码

perl script.pl data.txt 10

use warnings;
use strict;
use Getopt::Std

unless (defined $DESIRED_LENGTH and $DESIRED_LENGTH =~ /^[0-9]+$/) {
my $DESIRED_LENGTH ;
while (<>) {
    chomp; # remove trailing newline
    if (m/^>/) {          # if line starts with '>'
        print "$_\n";     # just print it
    } else {
        my $i = 0;
        while ($i + $DESIRED_LENGTH <= length($_)) {
            print substr($_, $i, $DESIRED_LENGTH);
            print "\n";
            $i++;
        }
    }
}
}

或者我也试过这个

use warnings;
use strict;
use Getopt::Std

getopts('i');
our($opt_i)
my $DESIRED_LENGTH = $opt_i;
while (<>) {
    chomp; # remove trailing newline
    if (m/^>/) {          # if line starts with '>'
        print "$_\n";     # just print it
    } else {
        my $i = 0;
        while ($i + $DESIRED_LENGTH <= length($_)) {
            print substr($_, $i, $DESIRED_LENGTH);
            print "\n";
            $i++;
        }
    }
}

【问题讨论】:

  • 第一个会引发错误,因为它违反了strict 的要求。修复其中的错误后,第二个会做什么?
  • 另外,Getopt::Long 是首选。更加用户友好,并且在严格时玩得更好。
  • @Shawn 你能给我一个解决方案吗?我一直在研究这个简单的问题 1 天,但我无法弄清楚
  • say substr($_, 0, $desired_length, "") while length($_);
  • @ikegami 你觉得剩下的代码还可以吗?

标签: perl


【解决方案1】:
  • 您缺少几个分号。
  • 您没有确保提供了 -i,也没有提供默认值。
  • 您没有告诉getopts -i 选项需要一个参数。
  • 您没有验证提供的长度。
  • 您将 $i 增加了 1,而不是您已经打印了多少。
  • 您正在切断每个序列的结尾,除非它们恰好是指定长度的精确倍数。如果序列足够短,这可能会导致整个序列丢失。
  • -ilength 的一个奇怪选择,但也许您正试图与另一个工具保持一致?
  • 您正在咀嚼以 ^ 开头的行,只是为了在后面添加换行符。

固定:

use warnings;
use strict;
use feature qw( say );

use Getopt::Std;

our $opt_i;
getopts('i:');
die("Illegal value for -i\n") if defined($opt_i) && $opt_i !~ /^[1-9][0-9]*\z/;

my $max_len = $opt_i // 70;

while (<>) {
    if (/^>/) {
        print;
    } else {
        chomp;
        while (length($_)) {
           say substr($_, 0, $max_len, "");
        }
    }
}

当然,如果文件中的序列先前被包装成比指定长度短的行长度,则上述程序不会将它们扩展到所需的长度。

use warnings;
use strict;
use feature qw( say );

use Getopt::Std;

our $opt_i;
getopts('i:');
die("Illegal value for -i\n") if defined($opt_i) && $opt_i !~ /^[1-9][0-9]*\z/;

my $desired_len = $opt_i // 70;

my $seq;
while (1) {
   my $line = <>;
   if (!defined($line) || $line =~ /^>/) {
      while (length($seq)) {
         say substr($seq, 0, $desired_len, "");
      }

      last if !defined($line);

      print($line);
      $seq = "";
   } else {
      chomp($line);
      $seq .= $line;
   }
}

【讨论】:

  • 我收到此错误perl second_split.pl data.txt 10 Global symbol "$i" requires explicit package name at second_split.pl line 10. Execution of second_split.pl aborted due to compilation errors.
  • 您以前肯定见过这个错误并且知道它的含义。或者google一下。我们会帮助你,但你必须开始付出一些努力!
  • 自从您发布了答案,我试图找到问题并自己解决。例如这里 stackoverflow.com/questions/26226034/… 但我没有看到 () 有任何错误,我应该将其更改为 {} 并且 I 超出 while 循环 stackoverflow.com/questions/23854436/…
  • 我遇到了一些问题,我会尝试解决它,如果它有效,那么我接受并喜欢你的回答,我像这样运行你的代码perl second_split.pl data.txt -I 10,但我得到了错误。感谢您的所有帮助
  • 我接受它,我自己的代码打印以&gt; 开头的行,但你的放弃了,是否有可能也添加它?
【解决方案2】:

如果您的数据在“d”文件中;

perl -ne 'if(/^>s.+\n/) {chomp; $_.="\n".<>; /^(>s.+\n)(\w+\n)/; print "\n$1"; print substr $2,$_ for 0..9}' d

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-11
    • 2017-06-17
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    • 2014-10-17
    • 2014-11-05
    • 2012-11-02
    相关资源
    最近更新 更多