如何将多个通配符合并到单个 shell 命令中?

问题描述 投票:0回答:1

我正在尝试使用snakemake来自动化我们迄今为止手工完成的一些事情。 我有一个问题,我想调用一个具有许多可能的输出文件的脚本。一个最小的非工作示例是这样的:

rule all:
    input:
        expand("{year}.txt", year=["15","16","17"]),

rule make_file:
    output:
       "{year}.txt",
    run:
        year_list = wildcards.year
        shell("python make_txt.py  --year {year_list}")

其中 make_txt.py 只是:

from argparse import ArgumentParser
parser =  ArgumentParser()
parser.add_argument('--year', nargs='*')

args = parser.parse_args()
for year in args.year:
    with open(f"{year}.txt",'w') as f:
        pass

此脚本可以将列表作为参数,然后生成多个文件,每个通配符一个文件。但它也可以获取一个列表,然后一次运行完成所有操作。我想要的是snakemake只调用一次make_file并执行

python make_txt.py --year 15 16 17
。我需要这个,因为我使用的实际代码是以循环通配符的方式编写的,并且在此之前需要进行大量设置,因此逐个运行作业会浪费大量时间。

我尝试在参数中运行某种解析,我认为这可能是正确的方法。我有什么遗漏的吗? 这个问题几乎也是我想要的。 从那里实施解决方案我的蛇文件是:

years = ["15","16","17"]
rule all:
    input:
        expand("{year}.txt", year=years),

rule make_file:
    output:
       expand("{year}.txt",year=years),
    params:
        years = years,
    shell:
        "python make_txt.py  --year {params.years}"

调用规则全部现在可以正确运行创建三个文件的单个作业。然而,我失去了使用通配符的能力,我仍然非常想做。我的真实代码有很多参数,并且像这样“硬编码”它们,每次我想要输出文件的不同子集时,我都需要更改蛇文件,而不是仅仅通过通配符调整目标。 理想的情况是提供一个列表作为通配符,有点像

snakemake [16,17,18].txt
然后将被解释为
wildcards.year = 15 16 17
。有什么办法可以实现这个功能吗?

python workflow snakemake
1个回答
0
投票

我认为你不能用文件来做到这一点,但也许可以使用 config 选项或文件

# config.yaml
years:
  - 15
  - 16
  - 17

# Snakefile
configfile: "config.yaml"
if isinstance(config['years'], list):
    years = config['years']
else:
    years = config['years'].split(',')
rule all:
    input:
        expand("{year}.txt", year=years),

rule make_file:
    output:
       expand("{year}.txt",year=years),
    params:
        years = years,
    shell:
        "python make_txt.py  --year {params.years}"

然后您可以通过调整 config.yaml 内容或使用

snakemake --config years=10,11,12
来自定义执行。

传入文件名的问题在于,snakemake 将文件视为特殊文件,并且没有任何语法可以说明“此规则将创建您需要的所有年份”而不更改另一个变量。您可以使用检查点,但最终您需要说明规则将生成什么,并且使用配置变量是最简单的界面。

© www.soinside.com 2019 - 2024. All rights reserved.