Reputation: 15633
In a GNU Makefile (on an Ubuntu Linux system), how may I remove the filename suffix of each filename in a list in such a way that the filenames are truncated at the first dot?
Suppose I have
NAMES = file1.a.b.c file2.x.y.z file3.b file4.foo
where the names may come from a filename globbing expansion using $(wildcard file*)
.
I would like to end up with
NEWNAMES = file1 file2 file3 file4
or possibly even
NEWNAMES = file1.quux file2.quux file3.quux file4.quux
(not necessarily in this order)
The $(basename ...)
function only strips the last suffix from the names.
In a shell supporting arrays, I would have used something like "${names[@]%%.*}"
or "${names[@]/%.*/.quux}"
.
The reason for wanting to do this is that we're working with a bioinformatics environment where files have a known filename prefix, but their suffix may be any combination of .fa
, .fas
, .fasta
(etc.), with the possibility of these suffixes doubling up (as in .fa.fa
) and also having a file compressor suffix, such as .gz
, at the end.
We would like to transform the filenames into normalised prefix.suffix
filenames in the Makefile, regardless of how complex the initial filename suffix was.
Upvotes: 2
Views: 955
Reputation: 2898
If you want a more flexible approach, you can use gmtt, a GNUmake library:
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)))
Output:
$ 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.
The glob-matcher returns a list of separated strings which you can process further.
Upvotes: 1
Reputation: 100946
If you want to do it with make functions without using a shell, you can use something like this:
NAMES := $(foreach F,$(wildcard file*),$(firstword $(subst ., ,$F)))
Upvotes: 3
Reputation: 36
I'm not sure what platforms are targeted here (do we have a SUSv3 compliant /bin/sh) as well as any requirements on the names.
If it's acceptable that names can't contain whitespace, I think a simple
NEWNAMES = $(shell for p in $(NAMES); do echo $${p%%.*};done)
comes close enough and is easy to understand.
Upvotes: 1