Python 如何在snakemake输出中执行简单的字符串操作

Python 如何在snakemake输出中执行简单的字符串操作,python,snakemake,Python,Snakemake,我正在创建我的第一个snakemake文件,我需要对我的输出的值执行一个简单的字符串操作,以便我的shell命令按预期工作: rule sketch: input: 'out/genomes.txt' output: 'out/genomes.msh' shell: 'mash sketch -l {input} -k 31 -s 100000 -o {output}' 我需要将split函数应用于{output},以便只使用扩展名之前的文件名。我在文档或相

我正在创建我的第一个snakemake文件,我需要对我的
输出的值执行一个简单的字符串操作,以便我的
shell
命令按预期工作:

rule sketch:
  input:
    'out/genomes.txt'
  output:
    'out/genomes.msh'
  shell:
    'mash sketch -l {input} -k 31 -s 100000 -o {output}'

我需要将
split
函数应用于
{output}
,以便只使用扩展名之前的文件名。我在文档或相关问题中找不到任何内容。

您可以使用参数字段:

rule sketch:
  input:
    'out/genomes.txt'
  output:
    'out/genomes.msh'
  params:
    dir = 'out/genomes'
  shell:
    'mash sketch -l {input} -k 31 -s 100000 -o {params.dir}'

避免重复文本。除非将输入/输出转换为通配符+扩展名,否则不要使用参数。否则,你就会有一条很难维持的规则

input:
    "{pathDIR}/{genome}.txt"
output:
    "{pathDIR}/{genome}.msh"
params:
    dir: '{pathDIR}/{genome}'
否则

我似乎无法使用输出通配符使切片表示法在参数中工作。这里是run指令

from subprocess import call

rule sketch:
  input:
    'out/genomes.txt'
  output:
    'out/genomes.msh'
  run:
    callString="mash sketch -l " + str(input) + " -k 31 -s 100000 -o " + str(output)[:-4]
    print(callString)
    call(callString, shell=True)
蟒蛇是蛇的基础。我更喜欢“run”指令而不是“shell”指令,因为我发现它确实解锁了许多漂亮的Python功能。参数和各种事物的访问与“shell”指令略有不同

例如


您可以在shell命令中删除扩展

rule sketch:
  input:
    'out/genomes.txt'
  output:
    'out/genomes.msh'
  shell:
    'mash sketch -l {input} -k 31 -s 100000 -o $(echo "{output}" | sed -e "s/.msh//")'

使用通配符的替代解决方案:

rule all:
  input: 'out/genomes.msh'

rule sketch:
  input:
    '{file}.txt'
  output:
    '{file}.msh'
  shell:
    'mash sketch -l {input} -k 31 -s 100000 -o {wildcards.file}'
未经测试,但我认为这应该有效


params
解决方案相比,它的优点是泛化效果更好。

最好使用
params

rule sketch:
    input:
        'out/genomes.txt'
    output:
        'out/genomes.msh'
    params:
        prefix=lambda wildcards, output: os.path.splitext(output[0])[0]
    shell:
        'mash sketch -l {input} -k 31 -s 100000 -o {params.prefix}'

最好使用
params
而不是
run
指令,因为
run
指令不能与conda环境结合使用。

这是迄今为止最优雅的解决方案,尽管原则上可以对输入/输出执行非常基本的操作。悲哀的
rule sketch:
    input:
        'out/genomes.txt'
    output:
        'out/genomes.msh'
    params:
        prefix=lambda wildcards, output: os.path.splitext(output[0])[0]
    shell:
        'mash sketch -l {input} -k 31 -s 100000 -o {params.prefix}'