GNU Make:删除第一个点后文件名的所有部分
GNU Make: Remove all parts of filename after first dot
在 GNU Makefile 中(在 Ubuntu Linux 系统上),我如何删除列表中每个文件名的文件名后缀,以便在第一个文件名被截断点?
假设我有
NAMES = file1.a.b.c file2.x.y.z file3.b file4.foo
名称可能来自使用 $(wildcard file*)
的文件名通配扩展。
我想以
结尾
NEWNAMES = file1 file2 file3 file4
甚至可能
NEWNAMES = file1.quux file2.quux file3.quux file4.quux
(不一定是这个顺序)
$(basename ...)
函数仅从名称中删除 last 后缀。
在 shell 支持数组中,我会使用类似 "${names[@]%%.*}"
或 "${names[@]/%.*/.quux}"
的东西。
想要这样做的原因是我们正在使用一个生物信息学环境,其中文件具有已知的文件名前缀,但它们的后缀可以是 .fa
、.fas
的任意组合.fasta
(等),这些后缀有可能加倍(如 .fa.fa
),最后还有一个文件压缩器后缀,例如 .gz
。
我们希望在 Makefile 中将文件名转换为标准化的 prefix.suffix
文件名,无论初始文件名后缀有多复杂。
我不确定这里针对的是什么平台(我们是否有符合 SUSv3 的 /bin/sh)以及对名称的任何要求。
如果名称不能包含空格是可以接受的,我认为一个简单的
NEWNAMES = $(shell for p in $(NAMES); do echo $${p%%.*};done)
足够接近并且很容易理解。
如果你想在不使用 shell 的情况下使用 make 函数来完成它,你可以使用这样的东西:
NAMES := $(foreach F,$(wildcard file*),$(firstword $(subst ., ,$F)))
如果你想要更灵活的方法,你可以使用 gmtt,一个 GNUmake 库:
include gmtt-master/gmtt-master/gmtt.mk
NAMES = file1.a.b.c file2.x.y.z file3.b file4.foo
$(info $(foreach fn,$(NAMES),$(call glob-match,$(fn),*.*)$(newline)))
NEWNAMES = file1.middle.quux file2.middle.quux file3.middle.quux file4.more.middle.quux
$(info $(foreach fn,$(NEWNAMES),$(call glob-match,$(fn),*.*.quux)$(newline)))
输出:
$ make
file1 . a.b.c
file2 . x.y.z
file3 . b
file4 . foo
file1 . middle .quux
file2 . middle .quux
file3 . middle .quux
file4 . more.middle .quux
make: *** Keine Ziele. Schluss.
glob-matcher returns 您可以进一步处理的分隔字符串列表。
在 GNU Makefile 中(在 Ubuntu Linux 系统上),我如何删除列表中每个文件名的文件名后缀,以便在第一个文件名被截断点?
假设我有
NAMES = file1.a.b.c file2.x.y.z file3.b file4.foo
名称可能来自使用 $(wildcard file*)
的文件名通配扩展。
我想以
结尾NEWNAMES = file1 file2 file3 file4
甚至可能
NEWNAMES = file1.quux file2.quux file3.quux file4.quux
(不一定是这个顺序)
$(basename ...)
函数仅从名称中删除 last 后缀。
在 shell 支持数组中,我会使用类似 "${names[@]%%.*}"
或 "${names[@]/%.*/.quux}"
的东西。
想要这样做的原因是我们正在使用一个生物信息学环境,其中文件具有已知的文件名前缀,但它们的后缀可以是 .fa
、.fas
的任意组合.fasta
(等),这些后缀有可能加倍(如 .fa.fa
),最后还有一个文件压缩器后缀,例如 .gz
。
我们希望在 Makefile 中将文件名转换为标准化的 prefix.suffix
文件名,无论初始文件名后缀有多复杂。
我不确定这里针对的是什么平台(我们是否有符合 SUSv3 的 /bin/sh)以及对名称的任何要求。
如果名称不能包含空格是可以接受的,我认为一个简单的
NEWNAMES = $(shell for p in $(NAMES); do echo $${p%%.*};done)
足够接近并且很容易理解。
如果你想在不使用 shell 的情况下使用 make 函数来完成它,你可以使用这样的东西:
NAMES := $(foreach F,$(wildcard file*),$(firstword $(subst ., ,$F)))
如果你想要更灵活的方法,你可以使用 gmtt,一个 GNUmake 库:
include gmtt-master/gmtt-master/gmtt.mk
NAMES = file1.a.b.c file2.x.y.z file3.b file4.foo
$(info $(foreach fn,$(NAMES),$(call glob-match,$(fn),*.*)$(newline)))
NEWNAMES = file1.middle.quux file2.middle.quux file3.middle.quux file4.more.middle.quux
$(info $(foreach fn,$(NEWNAMES),$(call glob-match,$(fn),*.*.quux)$(newline)))
输出:
$ make
file1 . a.b.c
file2 . x.y.z
file3 . b
file4 . foo
file1 . middle .quux
file2 . middle .quux
file3 . middle .quux
file4 . more.middle .quux
make: *** Keine Ziele. Schluss.
glob-matcher returns 您可以进一步处理的分隔字符串列表。