如何在命令行参数给定的数字范围内使用GNU Parallel

5

我正在尝试使用GNU Parallel和一些基本的生物信息工具,例如lastz。假设我有10个序列,我想对它们全部使用lastz,那么我可以使用以下命令:

parallel --dryrun lastz 'pathToFile/seq{}.fa query.fasta --format=text > LASTZ_results_seq{}' ::: {1..10} 

这很好用,可以返回:

lastz pathToFile/seq1.fa query.fasta --format=text > LASTZ_results_seq1
lastz pathToFile/seq2.fa query.fasta --format=text > LASTZ_results_seq2
lastz pathToFile/seq3.fa query.fasta --format=text > LASTZ_results_seq3
...
lastz pathToFile/seq10.fa query.fasta --format=text > LASTZ_results_seq10

但理想情况下,我希望这一步骤是bash脚本的一部分,该脚本接受三个命令行参数,因此序列的数量(例如1到10)在命令行中给出($2 = startValue,$3 = endValue)。我认为将其更改为以下内容将起作用:

parallel --dryrun lastz 'pathToFile/seq{}.fa query.fasta --format=text > LASTZ_results_seq{}' ::: {"$2".."$3"}

但是相反,它返回的是
lastz pathToFile//seq\{\1..\10\} query.fasta --format=text > LASTZ_results_seq\{\1..\10\}

请问有人能告诉我这里出了什么问题吗?看起来它把$2解释为1,$3解释为10,但是却不能将其视为一系列数字...

2个回答

8

Bash 范围不接受变量,请参考此帖子:

如何在 Bash 中迭代由变量定义的一系列数字?

因此,建议您将 {$1..$2} 更改为 $(seq $1 $2)。

例如,请参阅此测试脚本:

$ cat foo
parallel echo ::: {1..3}
parallel echo ::: {$1..$2}
parallel echo ::: $(seq $1 $2)

当输入 ./foo 1 3 时,它会产生以下输出:
1
2
3
{1..3}
1
2
3

3
为避免参数数量超过Shell命令行容量限制而出现问题,可以使用“seq $1 $2 | parallel echo”命令。 - Ole Tange

0

这不是你所询问的内容,但它可能是一个更好的解决方案:

parallel --dryrun lastz {} query.fasta --format=text '>' LASTZ_results_{/.} ::: pathToFile/seq*.fa

如果你遇到了参数列表太长的错误,请尝试以下方法:

printf '%s\n' pathToFile/seq*.fa | parallel --dryrun lastz {} query.fasta --format=text '>' LASTZ_results_{/.} 

这样你就不需要事先知道有多少个seq*.fa。


谢谢!我真的很喜欢这个解决方案,它简单得多。唯一的问题是,如果目录中有太多的seq*.fa(例如>100000),它会失败(“参数列表太长”)。有没有办法让它适用于任意数量的序列? - gizmo
哦,等等,不用了 - 刚刚注意到你在另一个解决方案上的评论了! - gizmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接