15

I'd like to count all the ordinary file on home directory with commands:

$ find ~ -type f | xargs echo | wc -w
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

It prompts

xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

What's the problem with usage?

user10726006
  • 585
  • 2
  • 5
  • 8
  • 1
    Do you really want to count the total number of *words* in all the filenames, or do you actually want to count the number of files? if the latter, then you can avoid processing the names altogether e.g. `find ~ -type f -printf 1 | wc -c` (print a single - arbitrary - character for each file, and count those) – steeldriver Jan 04 '19 at 05:27

1 Answers1

20

It appears that some of your filenames have apostrophes (single quote) in their names.

Luckily, find and xargs have ways around this. find's -print0 option along with xargs's -0 option produce and consume a list of filenames separated by the NUL (\000) character. Filenames in Linux may contain ANY character, EXCEPT NUL and /.

So, what you really want is:

 find ~ -type f -print0 | xargs -0 --no-run-if-empty wc -w

Read man find;man xargs.

waltinator
  • 35,099
  • 19
  • 57
  • 93
  • `find ~ -type f | wc -l` will work with more files, since xargs put all arguments on one command line and there is a limit in the number of args. – pim Jan 04 '19 at 05:29
  • 1
    @pim While it may be correct that `xargs` can suffer from argument list too long error, in this answer `-print0` and `xargs -0` combination is perfectly acceptable. See https://unix.stackexchange.com/a/83803/85039 – Sergiy Kolodyazhnyy Jan 04 '19 at 08:38
  • I think the OP's use of `wc -w` may have led you to suppose they want to count the words *inside* the files - they're actually using `xargs echo | wc -w` which will count the number of words in the file *names*, which I think is more likely an attempt to count the number of files (although it doesn't take into account that filenames may contain whitespace). (Likewise, `find ~ -type f | wc -l` doesn't take into account that filenames may contain newlines.) – steeldriver Jan 04 '19 at 13:34