Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want to see how many files are in subdirectories in there subdirectories to find out where all the inode usage is on the system. Kind of like I would do this for space usage

du -sh /*

which will basically give me the amount of space used in the directories off root. but in this case I want the number of files, not the size.

share|improve this question
    
    
I think that "how many files are in subdirectories in there subdirectories" is a confusing construction. If more clearly state what you want, you might get an answer that fits the bill. –  Steven D Nov 18 '10 at 0:02
    
@Steven feel free to rewrite it... I thought my example of du -sh /* made it pretty clear how I wanted the count to work. same thing, just count the files not the bytes. –  xenoterracide Nov 18 '10 at 7:45
    
As you mention inode usage, I don't understand whether you want to count the number of files or the number of used inodes. The two are different when hard links are present in the filesystem. Most, if not all, answers give the number of files. Don't use them on an Apple Time Machine backup disk. –  mouviciel Nov 19 '10 at 12:45
    
@mouviciel this isn't being used on a backup disk, and yes I suppose they might be different, but in the environment I'm in there are very few hardlinks, technically I just need to get a feel for it. figure out where someone is burning out there inode quota. –  xenoterracide Nov 19 '10 at 15:57

6 Answers 6

up vote 17 down vote accepted
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Thanks to Gilles and xenoterracide for safety/compatability fixes.

The first part: find -maxdepth 1 -type d will return a list of all directories in the current working directory. This is piped to...

The second part: while read -r dir; do begins a while loop - as long as the pipe coming into the while is open (which is until the entire list of directories is sent), the read command will place the next line into the variable "dir". Then it continues...

The third part: printf "%s:\t" "$dir"; will print the string in "$dir" (which is holding one of the directory names) followed by a tab.

The fourth part: find "$dir -f file" makes a list of all the files inside the directory name held in "$dir". This list is sent to..

The fifth part: wc -l; counts the number of lines that are sent into its standard input.

The final part: done simply ends the while loop.

So we get a list of all the directories in the current directory. For each of those directories, we generate a list of all the files in it so that we can count them all using wc -l. The result will look like:

./dir1: 234
./dir2: 11
./dir3: 2199
...
share|improve this answer
    
Always use read -r as plain read treats backslashes specially. Then echo -en "$dir:\t" will again mangle backslashes; a simple fix is to use printf '%s:\t' "$dir" instead. Next, $dir should be "$dir" (always use double quotes around variable substitutions). –  Gilles Nov 18 '10 at 1:40
    
seems to do what I want, thanks. –  xenoterracide Nov 18 '10 at 7:47
    
modified per @Giles suggestions find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" | wc -l; done –  xenoterracide Nov 18 '10 at 9:30
    
Thanks, guys. I fixed the answer to match. –  Shawn J. Goff Nov 18 '10 at 14:32
    
I'm adding sort -n -r -k2 to the end of this, for lots of directories, so that I know where the most usage is –  xenoterracide Jan 25 '11 at 10:45

Try:

find /path/to/start/at -type f -print | wc -l

as a starting point, or if you really only want to recurse through the subdirectories of a directory (and skip the files in that top level directory)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l
share|improve this answer
    
+1 for something | wc -l ... word count is such a nice little tool –  Johan Nov 16 '10 at 12:32
    
yeah but this only does 1 directory.... I'd like to get the count for all directories in a directory, and I don't want to run it seperately each time... of course I suppose I could use a loop... but I'm being lazy. –  xenoterracide Nov 16 '10 at 12:49
    
find works recursively through all sub directories by default. If you want it to work in multiple locations, you can specify all of them between find and -type. –  Didier Trosset Nov 16 '10 at 14:33
    
that second one certainly doesn't work.... I tried it on /home . I got 698035 . I should see about 6 numbers. –  xenoterracide Nov 16 '10 at 21:02
    
It works for me - are you sure you only have 6 files under /home? I'd be 100% certain you don't. –  Cry Havok Nov 17 '10 at 17:28

The following solution counts the actual number of used inodes starting from current directory:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

To get the number of files of the same subset, use:

find . | wc -l

For solutions exploring only subdirectories, without taking into account files in current directory, you can refer to other answers.

share|improve this answer
1  
Good idea taking hard links into account. Assuming GNU find, you don't need so many steps: find -printf '%i\n' | sort -u | wc -l. If you wanted to be portable, you'd need find . -exec ls -id {} + | cut … instead. –  Gilles Nov 19 '10 at 20:24

Try find . -type f | wc -l, it will count of all the files in the current directory as well as all the files in subdirectories. Note that all directories will not be counted as files, only ordinary files do.

share|improve this answer

Here's a compilation of some useful listing commands (re-hashed based on previous users code):

List folders with file count:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

List folders with non-zero file count:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

List folders with sub-folder count:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

List folders with non-zero sub-folder count:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

List empty folders:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

List non-empty folders with content count:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done
share|improve this answer
    
And btw.. if you want to have the output of any of these list commands sorted by the item count .. pipe the command into a sort : "a-list-command" | sort -n –  DolphinDream May 16 '13 at 16:00

Give this a try:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

It should work fine unless filenames include newlines.

share|improve this answer
    
way too recursive... I only want to see the top level, where it totals everything underneath it. totaled... this ends up printing every directory. –  xenoterracide Nov 16 '10 at 21:05
    
@xenoterracide: Try adding -maxdepth 1 immediately after the first find. If you want to include the number of subdirectories in your count, remove the -type f at the end (that should have really been ! -type d anyway, so that all non-directory files would have been included). –  Dennis Williamson Nov 16 '10 at 23:15

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.