在蛇形展开函数中正确转义句号



我正在编写一个蛇形管道,我在其中下载文件名包含许多句点的各种文件,我花了很长时间才使它正确地理解文件名。我基本上有两个规则,下载规则和目标规则。下面将它们简化如下:


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.Bgroup=normal还是dataset=101group=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"

(在定义任何规则之前)

最新更新