2012-09-07 15 views
5

Estoy escribiendo un Makefile y me quedo atascado en una función de filtro de limitación. De hecho, el filtro solo tiene un comodín.Makefile: Cómo aplicar un equivalente para filtrar en varios comodines

Lo que me gustaría hacer es: Tengo una lista de unos archivos, algunos a juego con la expresión regular blabla, otros no. Pero para esto necesito 2 comodines, así no puedo usar la función de filtro.

Me gustaría dividir mi lista original en 2 listas, una contiene todo el elemento que contiene la cadena blabla (filtro equivalente) y la otra que contiene la que no coincide (equivalente de filtrado).

gracias por su ayuda.

+1

¿Está utilizando GNU make o alguna otra variante? Y muestre su código actual, no está claro cuál es el problema. – Gilles

+1

Proporcione una lista de ejemplos de archivos, expresión de filtro y resultado deseado. Tal como lo describes ahora, no tengo claro por qué las funciones '$ (filter ...)' y '$ (filter-out ...)' no son lo suficientemente buenas para ti. –

+0

Gracias por su respuesta. Estoy usando gnu make. No tengo código para mostrar porque no puedo encontrar la manera de escribirlo. Digamos que tengo LIST = a_old_tt x_old_da a_new_da q_ty_we. Me gustaría clasificar el contenido LIST en: LIST_OLD que contiene todos los miembros de LIST que contienen la expresión old (a_old_tt y x_old_da en mi ejemplo) y LIST_NOT_OLD que contiene todos los miembros de LIST que no contienen la expresión old (a_new_da q_ty_we in mi ejemplo). – user1654361

Respuesta

1

Una de las mayores deficiencias de Make es su poca capacidad para manejar expresiones regulares. Las funciones filter y filter-out no pueden encontrar "viejo" en el medio de una palabra. Sugeriría este truco:

NOT_OLD = $(shell echo $(LIST) | sed 's/[^ ]*old[^ ]* *//g') 
OLD = $(filter-out $(NOT_OLD), $(LIST)) 
0

Podrías aprovechar las capacidades de manejo de cuerdas más avanzadas de tu caparazón. Asumiendo que usted tiene bash, podría utilizar lo siguiente en su makefile:

LIST := a_old_tt x_old_da a_new_da q_ty_we 
LIST_NOT_OLD := $(shell l=($(LIST)); echo $${l[@]//*old*}) 
LIST_OLD := $(filter-out $(LIST_NOT_OLD),$(LIST)) 

se puede encontrar una explicación del mecanismo fiesta de sustitución de cadenas en how to delete elements from an array based on a pattern. Se requiere el doble $ para mantener el signo $ en la invocación del shell.

7

Puede hacerlo sin ejecutar ningún comando externo. Definen las dos macros

containing = $(foreach v,$2,$(if $(findstring $1,$v),$v)) 
not-containing = $(foreach v,$2,$(if $(findstring $1,$v),,$v)) 

Ahora se pueden hacer

LIST := a_old_tt x_old_da a_new_da q_ty_we 
LIST_OLD := $(call containing,old,$(LIST)) 
LIST_NOT_OLD := $(call not-containing,old,$(LIST)) 
+0

+1, parece razonable, personalmente lo implementaría de la misma manera. –

+0

Limitando si necesita expresiones regulares completas para calcular el booleano 'que contiene', pero funciona para este caso particular. Personalmente, no me preocuparía por los comandos externos, ya que el rendimiento/ciclo interno de Make probablemente estará en el destino, en el comando de compilación/compilación. –

+0

Claro, como dijo Beta en su respuesta, 'make' no puede tratar con expresiones regulares, así que si las necesitas (pero OP no), obviamente no puedes usar esta respuesta. La primera reacción a este problema es a menudo sacar las armas grandes e invocar un comando externo para hacer la comparación, pero como muestra este caso, puede ser una exageración enorme. Evito ejecutar comandos externos tanto como sea posible, tanto para la portabilidad como para la velocidad. He visto grandes mejoras de rendimiento al deshacerse de los comandos externos innecesarios en los grandes sistemas de compilación basados ​​en make. – Idelic

Cuestiones relacionadas