I'm using Bash on Ubuntu and GNU Make 4.2.1.

I'm trying to write a Makefile that would perform simple operations on some data (.TXT files) I have. My different .TXT files are stored in 3 directories data/dir1 , data/dir2 and data/dir3.

For example, I would like to be able to type make count_dir1 or make count_dir2 or make count_dir3 in order to get the total number of lines withing a directory.

Without using a Makefile, I know how to do so when let's say my current directory is data/dir1 :

find . -name '*.TXT*' -type f | xargs wc -l

I get the number of lines of each file and the grand total which is exactly what I want.

Now, as for now, my targets basically look like that:

count_dir1: /home/data/dir1
    @cd /home/data/dir1 &&\
    find . -name '*.TXT*' -type f | xargs wc -l

count_dir2: /home/data/dir2
    @cd /home/data/dir2 &&\
    find . -name '*.TXT*' -type f | xargs wc -l

count_dir3: /home/data/dir3
    @cd /home/data/dir3 &&\
    find . -name '*.TXT*' -type f | xargs wc -l

So, everything works, but obviously, having three targets when I'm sure one would suffice is not efficient, but I don't know how to do so. I assume I would have to define some variables like:

dirs = /home/data/dir1 /home/data/dir2 /home/data/dir3

but then I'm not sure how to achieve my goal and from what I have read, I don't feel like it's a very good option to introduce variables that way.

Thank you in advance ! :)

  • Do you have subdirectories beneath data/dir1 etc.? If not, then wc -l data/dir1/*.TXT* would be enough to do the counting for the first directory. If you have many thousand of files, this would obviously not work, but so wouldn't your find solution (the total number of lines would be wrong since wc would be invoked multiple times).
    – Kusalananda
    Aug 21, 2020 at 11:32
  • Nope, no subdirectories !
    – Alex
    Aug 21, 2020 at 12:39

1 Answer 1


If gmake is standard compliant enough, you could use:

DIRS= /home/data/dir1 /home/data/dir2 /home/data/dir3


all: $(DIRS)

        cd $@ && find . -name '*.TXT*' -type f -exec wc -l {} +

.PHONY: is needed since the directories exist and do not depend from other targets.

Using xargs with find is deprecated since "execplus" has been introduced in 1988.

If you like shorthands for the long target names, you could add

count1: /home/data/dir1

count2: /home/data/dir2

count3: /home/data/dir3

to your makefile.

  • So how would I call my targets? I would have to type make /home/data/dir1 for instance? Is there a way to type let's make count1 that would behind call make /home/data/dir1 like an alias I suppose?
    – Alex
    Aug 21, 2020 at 12:20
  • When I called make /home/data/dir1 it returned 'make /home/data/dir1 is already up to date' which I get but I just wanted something to be printed to me, not a filed to be created so that message doesn't help ! Also I just saw your edit and tried called make count 1 but then I had make: Nothing to be done for 'count1' (guess the Makefile sees count1 as a target without any rule?
    – Alex
    Aug 21, 2020 at 12:35
  • So you forgot to add the .PHONY: ... line to the makefile or your version of gmake is broken.
    – schily
    Aug 21, 2020 at 12:44
  • Oops that's my bad I don't why I had changed my .PHONY: to .PHONY= . Thanks a lot :)
    – Alex
    Aug 21, 2020 at 12:47
  • also for further targets, how can I use DIRS as dependencies and call one of the dir depending on what my target is for instance if my target is subset_dir2 and I want to refer to /home/data/dir2 accordingly in my rule?
    – Alex
    Aug 21, 2020 at 13:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .