GNU Make: удалить все части имени файла после первой точки - PullRequest
2 голосов
/ 02 апреля 2019

В 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 .

В массивах, поддерживающих оболочку, я бы использовал что-то вроде "${names[@]%%.*}" или "${names[@]/%.*/.quux}".


Причина, по которой вы хотите это сделать, заключается в том, что мы работаем в среде биоинформатики, где файлы имеют известный префикс имени файла, но их суффикс может быть любой комбинацией .fa, .fas, .fasta (и т. Д.). ), с возможностью удвоения этих суффиксов (как в .fa.fa), а также с суффиксом компрессора файлов, такого как .gz, в конце.

Мы хотели бы преобразовать имена файлов в нормализованные prefix.suffix имена файлов в Makefile, независимо от того, насколько сложным был исходный суффикс имени файла.

Ответы [ 3 ]

2 голосов
/ 02 апреля 2019

Если вы хотите сделать это с функциями make без использования оболочки, вы можете использовать что-то вроде этого:

NAMES := $(foreach F,$(wildcard file*),$(firstword $(subst ., ,$F)))
1 голос
/ 02 апреля 2019

Если вам нужен более гибкий подход, вы можете использовать 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возвращает список разделенных строк, которые вы можете обрабатывать дальше.

1 голос
/ 02 апреля 2019

Я не уверен, какие платформы нацелены здесь (у нас есть SUSv3-совместимый / bin / sh), а также какие-либо требования к именам.

Если допустимо, чтобы имена не могли содержать пробелы, я думаю, что простой

NEWNAMES = $(shell for p in $(NAMES); do echo $${p%%.*};done) 

подходит достаточно близко и легко понять.

...