首页 > 解决方案 > 如何获得对目录及其子目录同样有效的规则

问题描述

我正在尝试制定一个在目录及其任何子子目录上都可以使用的规则(以避免必须多次重复该规则)。如果有子目录,我想访问子目录的名称。

我的方法是使子目录可选。鉴于通配符可以通过明确给出“。*”模式来接受空字符串,因此我尝试了以下规则:

rule test_optional_sub_dir:
    input:
        "{adir}/{bdir}/a.txt"
    output:
        "{adir}/{bdir,.*}/b.txt"
    shell:
        "cp {input} {output}"

我希望这条规则能同时匹配 A/b.txt 和 A/B/b.txt。

但是,A/b.txt 与规则不匹配。(A//b.txt 也不是 bdir 的省略,我猜双 / 在匹配发生之前被删除)。

以下规则适用于 A/b.txt 和 A/B/b.txt:

rule test_optional_sub_dir2:
    input:
        "{path}/a.txt"
    output:
        "{path,.*}/b.txt"
    shell:
        "cp {input} {output}"

但在这种情况下的问题是我无法轻松访问路径中目录的名称。我可以使用函数 pathlib.Path 来分解 {path} 但这似乎变得过于复杂。

有没有更好的方法来完成我想做的事情?

非常感谢你的帮助。

标签: snakemake

解决方案


通过一些进一步的摆弄,我发现了一些接近我想要的东西:假设我想要至少一个目录,并且它下面不超过 2 个可选目录。以下作品。唯一的缺点是 opt_dir1 和 opt_dir2 包含尾部斜杠,而不仅仅是目录的名称。

rule test_optional_sub_dir3:
    input:
        "{mand_dir}/{opt_dir1}{opt_dir2}a.txt"
    output:
        "{mand_dir}/{opt_dir1}{opt_dir2}b.txt"
    wildcard_constraints:
        mand_dir="[^/]+",
        opt_dir1="([^/]+/)?",
        opt_dir2="([^/]+/)?"
    shell:
        "cp {input} {output}"

如果有人有更好的方法,仍然对更好的方法感兴趣。


推荐阅读