如何在Snakemake中合并多通配符到单Shell命令并保留通配符功能
Snakemake批量调用脚本的最优实现
针对「单个年份通配符重复调用脚本、硬编码年份丢失灵活性」的问题,可通过动态捕获用户指定的输出子集+批量调用脚本的方式解决,既保留通配符灵活性,又避免重复初始化。
步骤1:配置基础参数与通配符约束
在Snakefile开头定义合法年份范围,限制通配符仅能取这些值,避免非法输入:
# 维护所有支持的年份 VALID_YEARS = {"16", "17", "18", "19"} # 约束年份通配符必须是合法值 wildcard_constraints: year="|".join(VALID_YEARS)
步骤2:用Checkpoint捕获目标年份子集
通过checkpoint提取用户命令行指定的输出文件对应的年份,生成临时文件记录待处理年份列表:
checkpoint collect_target_years: output: temp("target_years.txt") # 临时文件,任务完成后自动删除 shell: """ # 从命令行指定的输出中提取年份,去重后写入临时文件 echo {snakemake.output} | xargs -n1 basename | sed 's/\\.txt$//' | sort -u > {output} """
步骤3:编写批量处理规则
根据临时文件中的年份列表,单次调用脚本生成所有目标文件:
rule generate_txt_files: input: checkpoint("collect_target_years") output: # 动态生成需要输出的文件列表 lambda wildcards, input: expand("{year}.txt", year=open(input[0]).read().split()) params: # 将年份列表转为脚本可接收的参数格式 lambda wildcards, input: " ".join(open(input[0]).read().split()) shell: "python make_txt.py --years {params}"
使用方式
用户可灵活指定需要生成的文件:
- 生成单个年份:
snakemake 16.txt - 生成多个年份:
snakemake {16,17,18}.txt(shell brace expansion,会展开为三个文件) - 生成所有年份:
snakemake *.txt
无论指定多少个文件,脚本只会被调用一次,彻底解决重复初始化问题;同时保留通配符灵活性,无需硬编码年份。
内容的提问来源于stack exchange,提问作者Luka
相关产品推荐
相关产品推荐

