我正在编写一个蛇形管道,我在其中下载文件名包含许多句点的各种文件,我花了很长时间才使它正确地理解文件名。我基本上有两个规则,下载规则和目标规则。下面将它们简化如下:
rule download_files_from_s3:
input:
some input
params:
some params
output:
expand("destinationDir/{{sampleName}}.{{suffix}}")
shell:
shell:
"aws s3 cp input destinationDir"
rule targets:
input:
expand("destinationDir/{sampleName}.{suffix}", sampleName=sampleNames)
在这个公式中,snakemake编译成功,并正确地从s3下载文件到我想要的地方。但是,它无法找到它们,并且"显示最多等待5秒钟以等待丢失的文件"。我可以看到,当我在干跑模式下运行snakemake时,snakemake期望的文件形式为"destinationDir/sampleName.suffix"而实际上它们没有反斜杠:"destinationDir/sampleName.suffix"。我的第一个想法是去掉反斜杠,将规则更改为:
expand("destinationDir/{sampleName}.{suffix}", sampleName=sampleNames)
然而,这创建了一个过于贪婪的正则表达式。后缀的值应该是".params.txt"。当我运行无反斜杠版本时,snakemake计算通配符sampleName作为"sampleName.params"和通配符后缀作为"txt"我应该如何最好地做到这一点,要么通过强制扩展中的正则表达式匹配行为,要么让snakemaker正确解释"字符?到目前为止,我的努力还没有成功。
我不知道snakemake,但阅读他们的文档提到,您可以通过在通配符中提供正则表达式来避免歧义:
{wildcard,regex}
,
{sampleName,[^.]+}
引用文档:
[…]
一个文件名中的多个通配符可能导致歧义。考虑模式
{dataset}.{group}.txt
,并假设文件101.B.normal.txt
可用。不清楚在这种情况下是dataset=101.B
和group=normal
还是dataset=101
和group=B.normal
。因此通配符可以约束为给定的正则表达式。这里我们可以将通配符
dataset
限制为仅由数字组成,使用d+
作为相应的正则表达式。在Snakemake 3.8.0中,有三种方法来约束通配符。首先,可以在文件模式中约束通配符,方法是附加一个用逗号分隔的正则表达式:output: "{dataset,d+}.{group}.txt"
[…]
https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html通配符还要注意{{wildcard}}
将"掩码";通配符,如文档的expand
部分所述:
你也可以在expand中屏蔽一个通配符表达式,这样它就会被保留,例如
expand("{{dataset}}/a.{ext}", ext=FORMATS)
https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html the-expand-function
我不确定我应该如何理解&;mask&;但是阅读顶部的旁注让我想到这是一种逃避{
的特殊含义并使用字符串字面量{wildcard}
的方法。
注意,在执行相应的作业时,shell命令中的任何占位符(如
{input}
)总是被计算和替换,即使它们出现在注释中。为了避免求值和替换,你必须通过将括号加倍来掩盖它们,即{{input}}
。
https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html
简短的回答是您不需要转义句点,expand
中的字符串不是正则表达式。
如果您的后缀值总是"params.txt",一个简单的解决方案是指定:
expand("destinationDir/{sampleName}.params.txt", sampleName=sampleNames)
如果后缀是可变的,但您想以某种方式约束它,根据最新的文档,在后缀周围加上单括号并设置allow_missing
应该可以将suffix
保留为通配符,并且您应该能够(如本回答中提到的)使用通配符约束来指定潜在的后缀。假设后缀模式为".SOMETHING.txt":
rule targets:
wildcard_constraints:
suffix = ".[a-zA-Z]+.txt"
input:
expand("destinationDir/{sampleName}.{suffix}", sampleName=sampleNames, allow_missing=True)
(将suffix
包裹在双括号中也可以将其保留为通配符{suffix}
,而不是试图扩展它-您在download_files_from_s3
中的输出,正如现在所写的那样,也简化为
output: "destinationDir/{sampleName}.{suffix}"
在中,如果需要,您可以再次使用通配符约束。事实上,考虑到文件名的问题可能会在您的工作流程中持续存在,您可能希望通过添加
来全局设置通配符约束。wildcard_constraints:
suffix = ".[a-zA-Z]+.txt"
(在定义任何规则之前)