gpt4 book ai didi

linux - Perl 系统中的嵌套引号()

转载 作者:太空狗 更新时间:2023-10-29 11:13:29 28 4
gpt4 key购买 nike

我正在尝试修改 perl 脚本。这是我要修改的部分:

原文:

        system ("tblastn -db $BLASTDB -query $TMP/prot$$.fa \\
-word_size 6 -max_target_seqs 5 -seg yes -num_threads $THREADS -lcase_masking \\
-outfmt \"7 sseqid sstart send sframe bitscore qseqid\"\\
> $TMP/blast$$") && die "Can't run tblastn\n";

我正在尝试用以下内容替换系统(“tblastn.....”):

system ("cat $TMP/prot$$.fa | parallel --block 50k --recstart '>' --pipe \\ tblastn -db $BLASTDB -query - -word_size 6 -outfmt \'7 sseqid sstart send sframe bitscore qseqid\' -max_target_seqs 5 -seg yes -lcase_masking > $TMP/blast$$") && die "Can't run tblastn\n";

这用 GNU parallel 替换了普通的 tblastx 程序,它通过管道传输 tblastx 命令。在 bash 中运行上述命令(用实际文件替换临时输入)效果很好,但是当 perl 脚本尝试执行它时,错误日志(对于 tblastx)说它终止得太早,在 sseqids 之后。如果您在 bash 中运行没有转义字符的相同命令,则会发生相同的错误。

因此,我假设错误是由于“7 ssequids sstart...”周围的单引号没有被正确解析。我不确定如何在 perl 中正确地进行嵌套引号。我认为我做对了,因为它通过 bash 而不是通过 perl 脚本工作。我看了很多 perl 文档,所有内容都说转义字符\应该与引号或双引号一起使用。但对于我的实例来说,它不起作用。

有人可以提供有关为什么未处理报价的意见吗?

最佳答案

这里的问题几乎可以肯定是引用插值。每次你“掏空”时,你都会打开另一层引号。它在引号内的作用是一个问题,你是在做一个双引号 " - 它插入,还是一个单引号 ' 然后它把它当作一个文字, 在传递给下一个 shell 之前。

参见 perlop perl 如何引用。我建议您尝试像这样组装一个命令:

my $parallel = q{parallel --block 50k --recstart '>' --pipe};
my $outfmt = q{'7 sseqid sstart send sframe bitscore qseqid'};

print $parallel,"\n";
print $outfmt,"\n";

my $command = "cat $TMP/prot$$.fa | $parallel \\ tblastn -db $BLASTDB -query - -word_size 6 -outfmt $outfmt -max_target_seqs 5 -seg yes -lcase_masking > $TMP/blast$$";

print $command;
system ( $command );

(显然在将其传递给系统之前检查您的“命令”是否正确)

但是我可以建议一种不同的方法吗?如果不嵌入 catparallel,您可以在 perl 中本地执行此操作怎么样。

恐怕我并不完全熟悉您正在运行的命令,但它应该是某事,例如:

#!/usr/bin/perl

use strict;
use warnings;

open( my $input, "<", "$TMP/prot$$.fa" ) or die $!;

my $fork_manager = Parallel::ForkManager->new($THREADS);

while ( my $line = <$input> ) {
$fork_manager->start and next;
chomp $line;
system(
"tblastn -db $BLASTDB -query $line \\
-word_size 6 -max_target_seqs 5 -seg yes -lcase_masking \\
-outfmt \"7 sseqid sstart send sframe bitscore qseqid\"\\
> $TMP/blast$$"
) && die "Can't run tblastn\n";
$fork_manager->finish;
}
close ( $input );

如果输出合并是可取的,我可能会切换到使用线程:

#!/usr/bin/perl

use strict;
use warnings;
use IPC::Open2;
use threads;
use Thread::Queue;

my $num_threads = 8;

my $work_q = Thread::Queue -> new();
my $results_q = Thread::Queue -> new();

sub worker {
open2 ( my $blast_out, my $blast_in, "tblastn -db $BLASTDB -query - -word_size 6 -outfmt '7 sseqid sstart send sframe bitscore qseqid' -max_target_seqs 5 -seg yes -lcase_masking");
while ( my $query = $work_q -> dequeue ) {
print {$blast_in} $query;
$results_q -> enqueue ( <$blast_out> ); #one line - you'll need something different for multi-line results.
}
close ( $blast_out );
close ( $blast_in );
}

sub collate_results {
open ( my $output, "$TMP/results.$$" ) or die $!;
while ( my $result = $results_q -> dequeue ) {
print {$output} $result,"\n";
}
close ( $output );
}

my @workers;
for (1..$num_threads) {
push ( @workers, threads -> create ( \&worker ) );
}

my $collator = threads -> create ( \&collate_results );

open( my $input, "<", "$TMP/prot$$.fa" ) or die $!;
while ( my $line = <$input> ) {
chomp $line;
$work_q -> enqueue ( $line );
}
close ( $input );
$work_q -> end;

foreach my $thr ( @workers ) {
$thr -> join();
}
$results_q -> end;

$collator -> join;

现在我明白,这两个可能看起来更复杂。但它们更多地是关于如何将 perl 扩展到并行执行的示例,因为这样做与运行 perl 相比,您拥有更多的范围和灵 active ,但可以“掏空”做事。

关于linux - Perl 系统中的嵌套引号(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30067878/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com