awk 命令在 snakemake --use-singularity 中失败
awk command fails in snakemake --use-singularity
我正在尝试将 Snakemake 与 Singularity 结合使用,我注意到使用 Singularity 时一个简单的 awk
命令不再有效。最后一行中的 </code> 被替换为 bash 而不是被 <code>awk
用作第一个字段。
这是一个最小的工作示例(Snakefile):
singularity: "docker://debian:stretch"
rule all:
input: "test.txt"
rule test:
output:
"test.txt"
shell:
"cat /etc/passwd | awk -F':' '{{print }}' > {output}"
当我 运行 snakemake
没有奇点时,输出 test.txt
看起来符合预期(仅包含用户名)。当我 运行 snakemake --use-singularity
时,文件包含整行,例如root:x:0:0:root:/root:/bin/bash
.
这是来自Snakemake的日志:
$ snakemake --use-singularity --printshellcmd
Building DAG of jobs...
Using shell: /usr/bin/bash
Provided cores: 1
Rules claiming more threads will be scaled down.
Job counts:
count jobs
1 all
1 test
2
rule test:
output: test.txt
jobid: 1
cat /etc/passwd | awk -F':' '{print }' > test.txt
Activating singularity image /scratch/test/.snakemake/singularity/fa9c8c7220ff16e314142a5d78ad6cff.simg
Finished job 1.
1 of 2 steps (50%) done
localrule all:
input: test.txt
jobid: 0
Finished job 0.
2 of 2 steps (100%) done
我试过你的例子,它在最新的 Snakemake 5.1.4 版本上运行良好。您确定在更新到最新版本后这仍然是您的问题吗?
当运行和bash -c
时,$
需要转义。
$ bash -c "cat temp.tab | awk '{if ($1==1) print;}' " | head -2
1 26554252 26554595 1 1
1 156246251 156246680 2 2
$ bash -c "cat temp.tab | awk '{if (==1) print;}' " | head -2
awk: cmd. line:1: {if (==1) print;}
awk: cmd. line:1: ^ syntax error
将您的 snakemake 代码更改为:
...
shell:
"cat /etc/passwd | awk -F':' '{{print $1}}' > {output}"
我遇到了类似的问题,经过反复试验终于解决了。目前(2018 年 11 月,对于 Snakemake 5.3),这有点没有记录,所以我认为把它放在这里以备将来参考以帮助其他人......
上面的所有例子都错误地使用了双引号和 bash -c,这不是 Snakemake 构造它的方式。相反,Snakemake 使用 bash -c ' modified_command '
调用 Singularity,因此使用单引号。
首先,这改变了特殊字符在命令中的处理方式。其次,截至目前,Snakemake 将实际命令中的所有单引号替换为转义版本 \'。但是,这仅适用于与 Singularity 一起使用时。
因此,如果您的命令包含单引号,则在使用 --use-singularity 提交时或在正常模式下 运行 时,事情会中断。我知道在这两种情况下都有效的唯一可行解决方案如下:
shell: """awk "{{OFS="\t"}};{{print $2}}" {input}"""
因此,以下规则适用:
- 不要在命令中使用单引号,否则会被替换,这会导致错误。
- 转义某些字符,例如 \t 转义为 \\t,$ 转义为 \$,{ 转义为 {{.
- 使用三引号将命令行调用括起来。
希望对您有所帮助,一旦有实施更新,我会更新此 post。
我正在尝试将 Snakemake 与 Singularity 结合使用,我注意到使用 Singularity 时一个简单的 awk
命令不再有效。最后一行中的 </code> 被替换为 bash 而不是被 <code>awk
用作第一个字段。
这是一个最小的工作示例(Snakefile):
singularity: "docker://debian:stretch"
rule all:
input: "test.txt"
rule test:
output:
"test.txt"
shell:
"cat /etc/passwd | awk -F':' '{{print }}' > {output}"
当我 运行 snakemake
没有奇点时,输出 test.txt
看起来符合预期(仅包含用户名)。当我 运行 snakemake --use-singularity
时,文件包含整行,例如root:x:0:0:root:/root:/bin/bash
.
这是来自Snakemake的日志:
$ snakemake --use-singularity --printshellcmd
Building DAG of jobs...
Using shell: /usr/bin/bash
Provided cores: 1
Rules claiming more threads will be scaled down.
Job counts:
count jobs
1 all
1 test
2
rule test:
output: test.txt
jobid: 1
cat /etc/passwd | awk -F':' '{print }' > test.txt
Activating singularity image /scratch/test/.snakemake/singularity/fa9c8c7220ff16e314142a5d78ad6cff.simg
Finished job 1.
1 of 2 steps (50%) done
localrule all:
input: test.txt
jobid: 0
Finished job 0.
2 of 2 steps (100%) done
我试过你的例子,它在最新的 Snakemake 5.1.4 版本上运行良好。您确定在更新到最新版本后这仍然是您的问题吗?
当运行和bash -c
时,$
需要转义。
$ bash -c "cat temp.tab | awk '{if ($1==1) print;}' " | head -2
1 26554252 26554595 1 1
1 156246251 156246680 2 2
$ bash -c "cat temp.tab | awk '{if (==1) print;}' " | head -2
awk: cmd. line:1: {if (==1) print;}
awk: cmd. line:1: ^ syntax error
将您的 snakemake 代码更改为:
...
shell:
"cat /etc/passwd | awk -F':' '{{print $1}}' > {output}"
我遇到了类似的问题,经过反复试验终于解决了。目前(2018 年 11 月,对于 Snakemake 5.3),这有点没有记录,所以我认为把它放在这里以备将来参考以帮助其他人......
上面的所有例子都错误地使用了双引号和 bash -c,这不是 Snakemake 构造它的方式。相反,Snakemake 使用 bash -c ' modified_command '
调用 Singularity,因此使用单引号。
首先,这改变了特殊字符在命令中的处理方式。其次,截至目前,Snakemake 将实际命令中的所有单引号替换为转义版本 \'。但是,这仅适用于与 Singularity 一起使用时。
因此,如果您的命令包含单引号,则在使用 --use-singularity 提交时或在正常模式下 运行 时,事情会中断。我知道在这两种情况下都有效的唯一可行解决方案如下:
shell: """awk "{{OFS="\t"}};{{print $2}}" {input}"""
因此,以下规则适用:
- 不要在命令中使用单引号,否则会被替换,这会导致错误。
- 转义某些字符,例如 \t 转义为 \\t,$ 转义为 \$,{ 转义为 {{.
- 使用三引号将命令行调用括起来。
希望对您有所帮助,一旦有实施更新,我会更新此 post。