¿Cómo cambiar la extensión de cada archivo en una lista con múltiples extensiones en GNU make?

82

En un makefile GNU, me pregunto si es posible, con una entrada de lista de archivos, hacer una salida de lista de archivos con nuevas extensiones.

En la entrada, obtengo esta lista:

FILES_IN=file1.doc file2.xls

Y me gustaría construir esta variable en mi archivo MAKE de la variable FILES_IN :

FILES_OUT=file1.docx file2.xlsx

Es posible ? Cómo ?

Es bastante difícil porque tengo que analizar la lista de archivos y detectar cada extensión (.doc, .xls) para reemplazarla por la extensión correcta.

TheFrancisOne
fuente

Respuestas:

141

Sustituir extensiones en una lista de nombres de archivos separados por espacios en blanco es un requisito común, y hay funciones integradas para esto. Si desea agregar un xal final de cada nombre en la lista:

FILES_OUT = $(FILES_IN:=x)

La forma general es $(VARIABLE:OLD_SUFFIX=NEW_SUFFIX). Toma el valor de VARIABLEy reemplaza OLD_SUFFIXal final de cada palabra que termina con este sufijo por NEW_SUFFIX(las palabras que no coinciden se dejan sin cambios). GNU hace llamadas a esta característica (que existe en cada implementación de make) referencias de sustitución .

Si lo que desea es el cambio .docen .docxy .xlsen .xlsxel uso de esta función, es necesario utilizar una variable intermedia.

FILES_OUT_1 = $(FILES_IN:.doc=.docx)
FILES_OUT = $(FILES_OUT_1:.xls=.xlsx)

También puede utilizar la sintaxis un poco más general $(VARIABLE:OLD_PREFIX%OLD_SUFFIX=NEW_PREFIX%NEW_SUFFIX). Esta característica no es exclusiva de GNU make, pero no es tan portátil como la simple sustitución de cambio de sufijo.

También hay una característica de creación de GNU que le permite encadenar múltiples sustituciones en la misma línea: la patsubstfunción .

FILES_OUT = $(patsubst %.xls,%.xlsx,$(patsubst %.doc,%.docx,$(FILES_IN)))
Gilles 'SO- deja de ser malvado'
fuente
3
O simplemente FILES_OUT := $(patsubst %,%x,$(FILES_IN))si la regla realmente puede hacerse tan genérica.
tripleee
¿Cuál es el nombre de este operador? Quiero consultar los manuales, pero no encuentro el nombre correcto.
rph
1
@rkioji ¿Qué operador? Le doy un enlace al manual de GNU make $(VARIABLE:OLD_SUFFIX=NEW_SUFFIX), ¿a qué más se refiere?
Gilles 'SO- deja de ser malvado'
@Gilles oh sí, no vi el enlace. Me referí a "sustitución". ¡Gracias!
rph