Объединить командные строки оболочки в змеиный мейк - PullRequest
0 голосов
/ 19 февраля 2020

Я хотел бы объединить две командные строки в одну, чтобы избежать промежуточных файлов.

workdir: "/path/to/workdir/"

rule all:
    input: 
        "my.filtered.vcf.gz"

rule bedtools:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        "/Tools/bedtools2/bin/bedtools intersect -a {input.invcf} -b {input.bedgz} -header -wa |"
        "/Tools/bcftools/bcftools annotate -c CHROM,FROM,TO,GENE -h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description="Gene name">') > {output.outvcf}"

Я получаю недопустимую синтаксическую ошибку. Я был бы признателен, если бы вы могли объяснить, как объединить несколько строк оболочки в змеиный мейк.

Ответы [ 2 ]

2 голосов
/ 19 февраля 2020

Возможно, вы получили неверный синтаксис из-за ", который вы используете здесь в своей оболочке: Description="Gene name">. Это закрывает вашу оболочку. Вы можете избежать этих кавычек или использовать синтаксис """:

rule bedtools:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        "/Tools/bedtools2/bin/bedtools intersect -a {input.invcf} -b {input.bedgz} -header -wa |"
        "/Tools/bcftools/bcftools annotate -c CHROM,FROM,TO,GENE -h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description=\"Gene name\">') > {output.outvcf}"

или

rule bedtools:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        """
        /Tools/bedtools2/bin/bedtools intersect -a {input.invcf} -b {input.bedgz} -header -wa | /Tools/bcftools/bcftools annotate -c CHROM,FROM,TO,GENE -h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description="Gene name">') > {output.outvcf}
        """

Обратите внимание, что вы можете использовать многострочное с """. Пример без труб:

shell:
    """
    bedtools .... {input} > tempFile 
    bcftools .... tempFile > tempFile2
    whatever .... tempFile2 > {output}
    """
1 голос
/ 19 февраля 2020

Экранирование двойных кавычек - проблема, но добавить немного больше к форматированию и конвейерам.

Я предпочитаю синтаксис переноса каждой строки в ", чтобы строки могли быть лучше расположены:

rule bedtools:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        "/Tools/bedtools2/bin/bedtools "
           "intersect "
           "-a {input.invcf} "
           "-b {input.bedgz} "
           "-header -wa "
        "| /Tools/bcftools/bcftools "
           "annotate "
           "-c CHROM,FROM,TO,GENE "
           "-h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description=\"Gene name\">') "
        "> {output.outvcf}"

Я считаю, что яснее видеть каждый аргумент и его легче менять, перемещая линии вокруг. Но обратите внимание, что завершающий пробел каждой строки требуется, и вы должны использовать явную новую строку, \n, если вы хотите отдельную команду. Когда подсказка напечатана, вывод хорошо отформатирован. С синтаксисом """ вы должны экранировать каждую новую строку с \ в конце, а пробелы в начале строки сохраняются при печати. ​​

Если вам нужно выполнить много работы, проверьте флаг трубы . Вы пишете свой первый шаг как правило, и snakemake создает именованный канал между правилами, представляя их как группу:

rule bedtools_intersect:
    input:
        invcf="/path/to/my.vcf.gz",
        bedgz="/path/to/my.bed.gz"
    output:
        outvcf=pipe("my.intersected.vcf.gz")
    shell:
        "/Tools/bedtools2/bin/bedtools "
           "intersect "
           "-a {input.invcf} "
           "-b {input.bedgz} "
           "-header -wa "
        "> {output.outvcf}"

rule bcftools_annotate:
    input:
        invcf="my.intersected.vcf.gz"
    output:
        outvcf="my.filtered.vcf.gz"
    shell:
        "/Tools/bcftools/bcftools "
           "annotate "
           "-c CHROM,FROM,TO,GENE "
           "-h <(echo '##INFO=<ID=GENE,Number=1,Type=String,Description=\"Gene name\">') "
           "{input.invcf} "
        "> {output.outvcf}"

Преимущество состоит в том, что вы можете повторно использовать каждое правило в своем конвейере для пересечения или аннотирования, избегая временные файлы.

...