2

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"
5

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
  • The test is not necessary if you simply add a trailing slash; e.g. ./images/*/ – user1686 Aug 22 '12 at 14:35
2

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
  • for x in $(find) is bad. – user1686 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
0

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

  • 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 – nelaaro Aug 27 '12 at 12:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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