Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

3 Answers 3

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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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