Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have file with a list of directories that I would like to know how many files are in each directory.

.../images/idsuffix/userids/

This will give me the count of files and directories for first 5 directories instead of for each directory.

find ./images/00{0..5}/ | wc

What I want is count of contents for each directory. I tried to pass it through xargs but does the same thing and produces a count for all the directories.

ls ./images/ > directories.lst  
cat directories.lst | xargs -i{} find {} | wc 

And this does not produce any output at all.

cat directories.lst | xargs -I{} bash -s "find {} | wc"
share|improve this question

You can use a for-loop:

for dir in ./images/* ; do echo $dir ; ls "$dir" | wc ; done

If you want the dot-files to be included, too, use ls -a.

If you want to count files in dot-dirs, too, use for dir in ./images/* ./images/.*.

If there are some non-directories, you can add a test:

for dir in ./images/* ; do
    if [[ -d $dir ]] ; then
        echo $dir
        ls "$dir" | wc
    fi
done
share|improve this answer
    
The test is not necessary if you simply add a trailing slash; e.g. ./images/*/ – grawity Aug 22 '12 at 14:35

If you want to read the directory list from a file do:

   $ for dir in $(cat directories.lst); do echo "$dir : `ls $dir | wc -l`"; done

You do not, however, need the file:

   $ for dir in $(find images/ -type d); do echo "$dir : `ls $dir | wc -l`"; done

And if you only want top level directories:

   $ for dir in $(find images/ -maxdepth 1 -type d); do echo "$dir : `ls $dir | wc -l`"; done

Finally, if you have spaces in your file names do:

   $ SAVEIFS=$IFS; IFS=$(echo -en "\n\b"); for dir in $(find images/ -type d); do echo "$dir : `ls $dir | wc -l`"; done; IFS=SAVEIFS
share|improve this answer
    
for x in $(find) is bad. – grawity Aug 22 '12 at 14:34
    
Very nice link @grawity, thanks. That is why I use the IFS in my last example though. Still, one more reason why choroba's answer is better :). – terdon Aug 22 '12 at 14:44
up vote 0 down vote accepted

Using sh in the -exec portion of the command you can start an other shell and run your commands in there quite nicely.

find . -name "*.dat" -exec csh -c 'echo -n $1; grep ID $1 | wc -l' {} {} \;

Or in my case, when counting files in directories. I use "ls -f" as it produces the ls output unsorted which is significantly faster the trying to sort the out put before counting.

with new line beween dir name and count

find /somedir/some/dir -type d -print -exec sh -c ' ls -f $1/* | wc -l' {} {} \;

Output looks like this

/dir/somedir/002/1066002
6

with tab between dir name and count

find /somedir/some/dir -type d -exec bash -c 'echo -en "$1\t"; ls -f $1/* | wc -l' {} {} \;

Output looks like this

/dir/somedir/002/1066002 6

http://www.compuspec.net/reference/os/solaris/find/find_and_execute_with_pipe.shtml

share|improve this answer
    
I don't think you need to pass the find result {} twice, since you're only accessing $1. – Daniel Beck Aug 27 '12 at 12:11
    
@DanielBeck with out the second {} the output dose not include the directory name and only shows the count for that directory – nelaar Aug 27 '12 at 12:31

You must log in to answer this question.

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