A file foo contains a list of filenames. Devise a single statement that stores in a variable count the total character count of the contents of these files.

closed as off-topic by derobert, slm, jasonwryan, Anthon, Bernhard Jan 1 '14 at 14:15

  • This question does not appear to be about Unix or Linux within the scope defined in the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 6
    StackExchange is not a place where you can find your homework assignments made for you... You ought to specify what you tried, what failed, what results you got. – John WH Smith Dec 31 '13 at 20:06
  • We're more than happy to help, but the operative word here is help, not do your homework for you. Show us what you've got so far. – slm Dec 31 '13 at 20:22
  • 5
    We're happy to help with specific questions about your assignment, but we don't do your assignment for you. – derobert Jan 1 '14 at 1:26
  • 1
    This was not an assignment. I was reading a book on UNIX and solving the exercises. I got stuck on this so asked – crisron Jan 1 '14 at 13:16
  • 1
    xargs cat -- < file.list | wc -c (assuming there's not file called - in that list and that the list is blank separated with quotes and backslash used to escape those blanks if they occur in filenames) – Stéphane Chazelas Jan 1 '14 at 17:07

Here's a way to do this in a single shell command.

<foo awk 'FILENAME=$0{while(getline<FILENAME>OUTPUT&&match($0,"$"))RSTOP-=RSTART}END{print-RSTOP}' | read count

This may not be the least awkward way to do it.

Be sure to tell me what your teacher thinks of it!

Some hints if you want to work it out:

  • Yes, it does work, in any POSIX environment. But in order to see it, you may need to use the right shell.
  • The choice of variable names may be a tad confusing (except when it isn't). Try renaming each of the and see which ones are significant.

Further hints:

• The while loop condition is (getline <INPUT > OUTPUT) && match($0, /$/) — be sure to work out what the < and > operators are here.
• If you think this isn't assigning to count, try in ksh or zsh.


Since apparently we're answering this question now.

Sample data

$ ls -1

$ cat afile{1..3}


$ cnt=0; for i in $(< filelist.txt);do \
   let cnt="cnt+$(wc -c $i | cut -d' ' -f1)";done; echo $cnt

In its expanded form:

$ cnt=0;
$ for i in $(< filelist.txt);do 
    let cnt="cnt+$(wc -c $i | cut -d' ' -f1)"
$ echo $cnt

The derobert's technique

One of our regulars mentioned that your instructor might have been looking for this method, which until today I was unaware of. In newer versions of the wc command there is a --files0-from= switch which can take a list of files and calculate the number of characters and the corresponding total.

The crux of the approach:

$ tr -s '\n' '\000' < filelist.txt | wc -c --files0-from=-


$ tr -s '\n' '\000' < filelist.txt | wc -c --files0-from=-
5 afile1
5 afile2
5 afile3
15 total

This can of course be cleaned up so that the result is stored in a value. Something like this:

$ tr -s '\n' '\000' < filelist.txt | \
     wc -c --files0-from=- | awk '/total/ {print $1}'

And finally you can store the results in a variable like so:

$ cnt=$(tr -s '\n' '\000' < filelist.txt | \
     wc -c --files0-from=- | awk '/total/ {print $1}')
  • There's a stray quote character in your answer, but otherwise that's not a downright awful way. – Gilles Jan 1 '14 at 1:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.