我正在尝试创建一个规则来在bedtools
中实现snakemake
,这将closest
一个包含另一个目录中的文件的文件。
我所拥有的是/home/bedfiles
目录下的20个床位文件:
1A.bed , 2B_83.bed , 3f_33.bed ...
我想要的是,在/home/bedfiles
目录下,有20个修改过的床文件:
1A_modified, 2B_83_modified , 3f_33_modified ...
所以bash命令是:
filelist='/home/bedfiles/*.bed'
for mfile in $filelist;
do
bedtools closest -a /home/other/merged.txt -b ${mfile} > ${mfile}_modified
因此,此命令将在_modified
目录中生成/home/bedfiles
扩展名的文件。
我想用Snakemake
实现这个,但是我一直有语法错误,我不知道如何修复。我的试用期是:
第1步:获取目录中第一部分床文件
FIRSTPART = [f.split(".")[0] for f in os.listdir("/home/bedfiles") if f.endswith('.bed')]
第2步:定义输出名称和文件夹
MODIFIED = expand("/home/bedfiles/{first}_modified", first=FIRSTPART)
第3步:在rule all
:
rule all:
input: MODIFIED
步骤4:制定具体规则以实施“最接近的床铺”
rule closest:
input:
input1 = "/home/other/merged.txt" , \
input2 = expand("/home/bedfiles/{first}.bed", first=FIRSTPART)
output:
expand("/home/bedfiles/{first}_modified", first=FIRSTPART)
shell:
""" bedtools closest -a {input.input1} -b {input.input2} > {output} """
它会在规则all的行中抛出错误,输入:
invalid syntax
您知道如何绕过此错误或以其他任何方式实现它吗?
PS:无法逐个写出文件的名称。
答案 0 :(得分:2)
删除expand
中input
和output
中closest
定义中对input.input2
的号召。您目前正在传递20个文件名为output
的向量和20个文件名为closest
的向量。
也就是说,您的规则closest
目前正在尝试运行一次并创建20个文件;而它应该运行20次并每次创建一个文件。
在input.input2
中,您希望output
成为单个文件,并且每次运行该规则时FIRSTPART = [f.split(".")[0] for f in os.listdir("/home/bedfiles") if f.endswith('.bed')]
print("These are the input files:")
print([f + ".bed" for f in FIRSTPART])
MODIFIED = expand("/home/bedfiles/{first}_modified", first=FIRSTPART)
print("These will be created")
print(MODIFIED)
rule all:
input: MODIFIED
rule closest:
message: """
Converts /home/other/merged.txt and /some/dir/xyz.bed
into /some/dir/xyz_modified
"""
input:
input1 = "/home/other/merged.txt",
input2 = "{prefix}.bed"
output: "{prefix}_modified"
shell:
"""
bedtools closest -a {input.input1} -b {input.input2} > {output}
"""
都是单个文件:
mkdir bedfiles
touch bedfiles/{a,b,c,d}.bed
这是一个实验:
将自己移到临时目录中,并在该目录中执行以下操作:
Snakefile
然后将名为import os
import os.path
import re
input_dir = "bedfiles"
input_files = [os.path.join(input_dir, f) for f in os.listdir(input_dir)]
print(input_files)
output_files = [re.sub(".bed$", "_modified", f) for f in input_files]
print(output_files)
rule all:
input: output_files
rule mover:
input: "{prefix}.bed"
output: "{prefix}_modified"
shell:
""" cp {input} {output} """
的文件添加到当前目录中,该文件包含以下代码
snakemake
然后在命令行使用@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%..
@rem agregado por marcgaso
set GRADLE_OPTS="-Dorg.gradle.native.dir=/tmp"
**strong text**
运行它。 Snakemake以目标为导向;它解决了如何根据现有文件制作所需的输出。
答案 1 :(得分:0)
简单一句:无效语法是指在input1 = "/home/other/merged.txt"
之后缺少{{1}}
希望能帮助到你
马克