2015-10-19 21 views
0

我有一個包含大量的文件和目錄下面的文件和目錄結構:合併文件的makefile導致不作任何目標

$ tree 
input/ 
├── C-1-28558666 
│ ├── MGRF-C1_S10_L001_R1_001.fastq.gz 
│ ├── MGRF-C1_S10_L001_R2_001.fastq.gz 
│ ├── MGRF-C1_S10_L002_R1_001.fastq.gz 
│ ├── MGRF-C1_S10_L002_R2_001.fastq.gz 
│ ├── MGRF-C1_S10_L003_R1_001.fastq.gz 
│ ├── MGRF-C1_S10_L003_R2_001.fastq.gz 
│ ├── MGRF-C1_S10_L004_R1_001.fastq.gz 
│ └── MGRF-C1_S10_L004_R2_001.fastq.gz 
├── C-2-28577664 
│ ├── MGRF-C2_S11_L001_R1_001.fastq.gz 
│ ├── MGRF-C2_S11_L001_R2_001.fastq.gz 
│ ├── MGRF-C2_S11_L002_R1_001.fastq.gz 
│ ├── MGRF-C2_S11_L002_R2_001.fastq.gz 
│ ├── MGRF-C2_S11_L003_R1_001.fastq.gz 
│ ├── MGRF-C2_S11_L003_R2_001.fastq.gz 
│ ├── MGRF-C2_S11_L004_R1_001.fastq.gz 
│ └── MGRF-C2_S11_L004_R2_001.fastq.gz 
... 

每個文件名包含R1或R2。 R1和R2的文件屬於一起,下面的commanand使用這兩個文件和一個dm6.fasta.bwt文件。

bwa mem ref/dm6.fasta.bwt input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz | samtools view -Sb - > BAMs/C-1-28558666/MGRF-C1_S10_L001.bam 

我試圖寫下面的Makefile規則:

BAMs/%.bam: $(addsuffix .bwt,${REFERENCE}) $(foreach SIDE,R1 R2, ../MGRF_NGS_KUMARAN-25071046/*/*${SIDE}*.fq.gz) 
    bwa mem ${REFERENCE} $(filter %.fq.gz,$^) | samtools view -Sb - > @> 

不過,我有:

$ make -n 
make: *** No targets. Stop. 

怎麼可能解決上述的Makefile?

+1

是,你還沒有告訴做出實際上構建任何文件。你剛剛給它一個模式來匹配目標文件名。這就是說,makefile目標/等。根本不會做你想做的事情。 –

+0

我剛從第一條規則開始。我如何告訴上面的例子來構建文件? – user977828

+0

你需要實際告訴make來構建目標:例如'make BAMs/file.bam'或者在你的makefile中有'all:BAMs/file.bam BAMs/otherfile.bam ...'這樣的目標,所以make有一個默認。但就像我說你的目標規則有一個*主機*的其他問題。 –

回答

1

您的第一個問題來自這樣一個事實,即如果沒有明確要求,模式規則不會創建目標。所以,你需要明確列出目標。在以下示例中,它們在BAMS make變量中列出,然後用作all目標的依存關係,該目標是makefile的第一個目標。 all因此是默認目標,打字makemake all將構建所有bams

你的第二個問題是處理每個bam目標的一對R1R2依賴關係。在GNU使靜態模式規則是非常有用的在這種情況下:

REFERENCE := ref/dm6.fasta 
DIRS := $(wildcard input/*) 
R1S := $(foreach dir,$(DIRS),$(wildcard $(dir)/*_R1_001.fastq.gz)) 
RR1S := $(patsubst input/%_R1_001.fastq.gz,%,$(R1S)) 
BAMS := $(patsubst %,BAMs/%.bam,$(RR1S)) 

all: $(BAMS) 

$(BAMS): BAMs/%.bam: $(REFERENCE).bwt input/%_R1_001.fastq.gz input/%_R2_001.fastq.gz 
    @mkdir -p $(dir [email protected]); \ 
    bwa mem $^ | samtools view -Sb - > [email protected] 

target: target-pattern: prerequisite-pattern是一個靜態模式規則。

GNU也使有幾個功能(callevalforeach),其可以在更復雜的示例中可以使用:

REFERENCE := ref/dm6.fasta 
DIRS := $(wildcard input/*) 
R1S := $(foreach dir,$(DIRS),$(wildcard $(dir)/*_R1_001.fastq.gz)) 
RR1S := $(patsubst input/%_R1_001.fastq.gz,%,$(R1S)) 
BAMS := $(patsubst %,BAMs/%.bam,$(RR1S)) 

all: $(BAMS) 

define BAM_rule 
BAMs/$(1).bam: $(REFERENCE).bwt input/$(1)_R1_001.fastq.gz input/$(1)_R2_001.fastq.gz 
    @mkdir -p $$(dir [email protected]); \ 
    bwa mem $$^ | samtools view -Sb - > [email protected] 
endef 

$(foreach r,$(RR1S),$(eval $(call BAM_rule,$(r)))) 

說明:

RR1S變量列出所有C-1-28558666/MGRF-C1_S10_L001莖。然後用它來構建列出目標的BAMS變量。 BAM_rule變量是規則的骨架,該規則從其相應的R1R2依賴關係構建目標bam$(1)是使用call函數時將擴展的參數:$(call BAM_rule,foo)將擴展爲BAM_rule,並用foo替代所有$(1)出現次數。請注意,一些$標誌必須加倍才能通過第一次擴展來保留。最後,

$(foreach r,$(RR1S),$(eval $(call BAM_rule,$(r)))) 

遍歷所有的莖和使用eval函數實例每幹,擴大和call專業一個BAM_rule

正常的化妝擴張然後將變換BAM_rule每個實例到規則,你將手工編寫給定目標:如果這是你的整個生成文件,然後你的問題

BAMs/C-1-28558666/MGRF-C1_S10_L001.bam: ref/dm6.fasta.bwt input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz 
    @mkdir -p BAMs/C-1-28558666; \ 
    bwa mem ref/dm6.fasta.bwt input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz | samtools view -Sb - > BAMs/C-1-28558666/MGRF-C1_S10_L001.bam 
+0

謝謝,但我不知道2 FASTQ(** R1 **和** R2 **)文件如何產生1個BAM文件,例如'input/C-1-28558666/MGRF-C1_S10_L001_R1_001.fastq.gz input/C-1-28558666/MGRF-C1_S10_L001_R2_001.fastq.gz | samtools view -Sb - > BAMs/C-1-28558666/MGRF-C1_S10_L001.bam'? – user977828

+0

「_001.fastq.gz」常量還是「_002.fastq.gz」...? –

+0

是的,'_001.fastq.gz'是恆定的,沒有'_002.fastq.gz'。 – user977828