0

I'm trying to count the total lines in the files within a directory. To do this I am trying to use a combination of find and wc. However, when I run find . -exec wc -l {}\;, I recieve the error find: missing argument to -exec. I can't see any apparent issues, any ideas?

2
  • 5
    You missed a space: find . -exec wc -l {} \; (space before \;). Commented Oct 6, 2014 at 17:20
  • I am not a clever man Commented Oct 6, 2014 at 17:22

2 Answers 2

4

You simply need a space between {} and \;

find . -exec wc -l {} \; 

Note that if there are any sub-directories from the current location, wc will generate an error message for each of them that looks something like that:

wc: ./subdir: Is a directory 

To avoid that problem, you may want to tell find to restrict the search to files :

find . -type f -exec wc -l {} \; 

Another note: good idea using the -exec option . Too many times people pipe commands together thinking to get the same result, for instance here it would be :

 find . -type f | xargs wc -l 

The problem with piping commands in such a manner is that it breaks if any files has spaces in it. For instance here if a file name was "a b" , wc would receive "a" and then "b" separately and you would obviously get 2 error messages: a: no such file and b: no such file.

Unless you know for a fact that your file names never have any spaces in them (or non-printable characters), if you do need to pipe commands together, you need to tell all the tools you are piping together to use the NULL character (\0) as a separator instead of a space. So the previous command would become:

find . -type f -print0 | xargs -0 wc -l 
Sign up to request clarification or add additional context in comments.

1 Comment

And, even better, POSIX stipulates that using + in place of ';' (or \;) works more or less the same as using xargs; find groups a bunch of file names together to run the command once per N file names (where N is not a controllable quantity, but depends on the maximum length of an argument list and the length of the file names).
1

With version 4.0 or later of bash, you don't need your find command at all:

shopt -s globstar wc -l **/* 

There's no simple way to skip directories, which as pointed out by Gui Rava you might want to do, unless you can differentiate files and directories by name alone. For example, maybe directories never have . in their name, while all the files have at least one extension:

wc -l **/*.* 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.