首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用正则表达式的Makefile模式规则

使用正则表达式的Makefile模式规则
EN

Stack Overflow用户
提问于 2019-02-28 09:27:31
回答 2查看 1.6K关注 0票数 0

我需要转换一堆名称如下的文件:

bar_S4_R1_001.fastq.gz

bar_S4_R2_001.fastq.gz

放入如下名称的文件中:

bar_R1_001.fastq.gz

bar_R2_001.fastq.gz

我想用Makefile pattern rule (docsexamples)来实现

我有一个这样的Makefile:

代码语言:javascript
运行
复制
SHELL:=/bin/bash
files:
    touch foo_S13_R2_001.fastq.gz
    touch foo_S13_R1_001.fastq.gz
    touch bar_S4_R2_001.fastq.gz
    touch bar_S4_R1_001.fastq.gz
    touch baz_S9_R2_001.fastq.gz
    touch baz_S9_R1_001.fastq.gz

FILES:=$(shell find . -name "*.fastq.gz")
.PHONY: $(FILES)

demo: $(FILES)
$(FILES):
    @printf "source: $@ , target should be: " ; \
    echo "$@" | sed -e 's|\(_S[0-9]*\)\(_R[12]_001.fastq.gz\)$$|\2|'

示例:

代码语言:javascript
运行
复制
$ make files
touch foo_S13_R2_001.fastq.gz
touch foo_S13_R1_001.fastq.gz
touch bar_S4_R2_001.fastq.gz
touch bar_S4_R1_001.fastq.gz
touch baz_S9_R2_001.fastq.gz
touch baz_S9_R1_001.fastq.gz

$ make demo
source: bar_S4_R1_001.fastq.gz , target should be: bar_R1_001.fastq.gz
source: foo_S13_R2_001.fastq.gz , target should be: foo_R2_001.fastq.gz
source: bar_S4_R2_001.fastq.gz , target should be: bar_R2_001.fastq.gz
source: baz_S9_R2_001.fastq.gz , target should be: baz_R2_001.fastq.gz
source: baz_S9_R1_001.fastq.gz , target should be: baz_R1_001.fastq.gz
source: foo_S13_R1_001.fastq.gz , target should be: foo_R1_001.fastq.gz

显然,我在这里的“demo”食谱中有我的"source“和"target”。我该如何使用Makefile模式规则来生成正确的文件呢?

EN

回答 2

Stack Overflow用户

发布于 2019-02-28 16:03:26

多亏了著名的foreach-eval-call组合和string substitution and analysis functions,GNU变得很巧妙,但却可行

代码语言:javascript
运行
复制
SHELL         := /bin/bash
.DEFAULT_GOAL := all
FILES         := foo_S13_R2_001.fastq.gz foo_S13_R1_001.fastq.gz bar_S4_R2_001.fastq.gz bar_S4_R1_001.fastq.gz baz_S9_R2_001.fastq.gz baz_S9_R1_001.fastq.gz
TARGETS       :=

.PHONY: all

# $(1): name of the source file in X_Y_Z_T.fastq.gz form
# tmp: X Y Z T.fastq.gz
# tmp1: X
# tmp2: Y
# tmp3: Z
# tmp4: T.fastq.gz
define MYRULE
tmp  := $$(subst _, ,$(1))
tmp1 := $$(word 1,$$(tmp))
tmp2 := $$(word 2,$$(tmp))
tmp3 := $$(word 3,$$(tmp))
tmp4 := $$(word 4,$$(tmp))

$$(tmp1)_$$(tmp3)_$$(tmp4): $(1)
    @printf 'source: %s, target should be: %s\n' "$$<" "$$@"

TARGETS += $$(tmp1)_$$(tmp3)_$$(tmp4)
endef
$(foreach f,$(FILES),$(eval $(call MYRULE,$(f))))

all: $(TARGETS)

$(FILES):
    @touch $@

演示:

代码语言:javascript
运行
复制
$ make
source: foo_S13_R2_001.fastq.gz, target should be: foo_R2_001.fastq.gz
source: foo_S13_R1_001.fastq.gz, target should be: foo_R1_001.fastq.gz
source: bar_S4_R2_001.fastq.gz, target should be: bar_R2_001.fastq.gz
source: bar_S4_R1_001.fastq.gz, target should be: bar_R1_001.fastq.gz
source: baz_S9_R2_001.fastq.gz, target should be: baz_R2_001.fastq.gz
source: baz_S9_R1_001.fastq.gz, target should be: baz_R1_001.fastq.gz

注意:MYRULE定义中的双$$是必不可少的,就像:=变量赋值一样(而不是=递归赋值)。

票数 2
EN

Stack Overflow用户

发布于 2019-02-28 18:53:22

第一个解决方案是vanilla make:

代码语言:javascript
运行
复制
PAT_START := _S
PAT_MID := 0 1 2 3 4 5 6 7 8 9
PAT_END := 0_ 1_ 2_ 3_ 4_ 5_ 6_ 7_ 8_ 9_

SUBSTITUTE := _

PAT12 := $(foreach c,$(PAT_START),$(addprefix $(c),$(PAT_END)))
PAT123 := $(foreach c,$(foreach c,$(PAT_START),$(addprefix $(c),$(PAT_MID))),$(addprefix $(c),$(PAT_END)))

$(info $(PAT12))
$(info $(PAT123))

FILES := foo_S13_R2_001.fastq.gz foo_S13_R1_001.fastq.gz bar_S4_R2_001.fastq.gz bar_S4_R1_001.fastq.gz baz_S9_R2_001.fastq.gz baz_S9_R1_001.fastq.gz

NEW_FILES := $(strip $(foreach f,$(FILES),$(foreach p,$(PAT12) $(PAT123),$(if $(subst $(subst $(p),,$(f)),,$(f)),$(subst $(p),$(SUBSTITUTE),$(f))))))

$(info $(FILES))
$(info $(NEW_FILES))

第二种是使用gmtt,这是一个GNUmake库,极大地简化了这些任务:

代码语言:javascript
运行
复制
include gmtt-master/gmtt-master/gmtt.mk

NEW_FILES := $(foreach f,$(FILES),$(call implode,$(call pick,1 4 5 6 7,$(call glob-match,$(f),*_S*_R[0-9]_*))))

$(info $(FILES))
$(info $(NEW_FILES))

请注意,gmtt解决方案使用的是glob而不是RE。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54917010

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档