Unfortunately, there's an error in that message and the correct function is as follows:
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))Usage is as follows. First, all C files in the current directory (or below).
$(call rwildcard,,*.c)Then all C files in /tmp:
$(call rwildcard,/tmp/,*.c)Multiple patterns can be used. Here are all C and H files:
$(call rwildcard,/tmp/,*.c *.h)
13 comments:
Thank you for posting this, I could not wrap my head around it myself.
Thank you, this post saved me a lot of headaches.
Thanks a lot!
Thanks a lot!
Many thanks for this, I was afraid I might have to do something very ugly, but thanks to you I guess I won't :D
A minor change of the code makes it capabale of searching in a list of base directories:
rwildcard = $(foreach d,$(wildcard $(addsuffix *,$(1))),$(call rwildcard,$(d)/,$(2)) $(filter $(subst *,%,$(2)),$(d)))
The $(addsuffix *,$(1)) instead of $(1)* expands a list of directories in the root invocation into directory candidates for further procesing.
Just a tip: A $(strip ...) around the complete RHS makes it better maintainable in case you want to print the output.
The archive is available at https://lists.gnu.org/archive/html/help-make/2006-03/msg00091.html
I think that rwildcard should be aligned with original wildcard semantics which accepts the pure file name as pattern. Therefore the improved implementation can look like this:
$(strip $(foreach d,$(wildcard ${1}/*),$(call rwildcard,${d},${2}) $(filter $(subst %%,%,%$(subst *,%,${2})),${d})))
Is it possible to ignore certain file names within the desired file extension
Vishwasu: give me an example of what you want to do. I suspect that getting the output from the wildcard function and then running it through $(filter) or $(filter-out) will be the answer but happy to help.
Like I would wanted to grep all *.txt and then
1. Filter out files with some pattern in the file name, lets say
2. Also in the contents of the file, If I find certain pattern lets
Vishwasu,
You can find all the .txt files in /tmp (and below) like this:
TXT_FILES := $(call rwildcard,/tmp/*.txt)
If you then want to then filter on the filenames you can use $(filter) and $(filter-out) (see https://www.gnu.org/software/make/manual/html_node/Text-Functions.html). Or $(findstring).
If you then want to look at the contents of the files then I think you should use some other external program and call it using $(shell). You could do this in GNU Make but it's going to be messy and a lot of work. You'd have to do something like this to read the contents of a file:
CONTENTS := $(shell cat $(FILENAME))
Then use $(findstring) to look for the pattern you want and then use $(if) to make a decision on whether the pattern exists. You can certainly do that but GNU Make's pattern matching is quite limited and so I can see how you'd quickly run into trouble.
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst\
*,%,$2),$d))
TXT_FILES := $(sort $(call rwildcard,/tmp,*.txt))
TXT_FILES_THAT_MATCH := $(foreach t,$(TXT_FILES),$(if $(findstring test,$t),$t)\
)
MATCHING_FILES := $(sort $(foreach f,$(TXT_FILES_THAT_MATCH),$(if $(findstring \
Jo,$(shell cat $f)),$f)))
$(info $(MATCHING_FILES))
Thanks , very helpful
Post a Comment