0

I am trying to write a one liner to find the number of files in each home directory. I am trying to do this as the other day I had situation where I ran out of inodes on /home. It took me a long time to find the offender and I want to shorten this process. This is what i have but it is not working.

for i in /home/*; do if [ -d "$i" ]; then cd $i find . -xdev -maxdepth 100 -type f |wc -l; fi done

When I run it, it prints a 0 for each home directory, and I remain in roots home directory.

However when I run just this part:

for i in /home/*; do if [ -d "$i" ]; then cd $i; fi done

I wind up in the last home directory leading me to believe I traversed them all.

And when I run this in each users home directory:

find . -xdev -maxdepth 100 -type f |wc -l

I get a legit answer.

Kara
  • 6,115
  • 16
  • 50
  • 57
menders65
  • 43
  • 8
  • are you missing a && after cd $i? also see other questions on SO, like http://stackoverflow.com/questions/9839055/searching-and-counting-files-in-directories-and-subdirectories-bash or http://stackoverflow.com/questions/15216370/how-to-count-number-of-files-in-each-directory – x29a Jan 28 '14 at 10:01
  • missing `;` after `cd $i`?? – Sakthi Kumar Jan 28 '14 at 10:02
  • Or just remove the `cd` altogeather (not best practice to have it in a shell script anyway) and put the path in your find. Also, why are you putting this as a "one liner"? – Reinstate Monica Please Jan 28 '14 at 10:03
  • Thanks @BroSlow so In the future if i need it in can just paste it in to the command line on any of the hundreds of servers – menders65 Jan 28 '14 at 11:01

2 Answers2

0

You're missing a terminating character after your cd. But more importantly, using cd can cause unwanted errors if you're not careful, try below instead (cd not needed).

for i in /home/*; do [ -d "$i" ] && echo "$i" && find "$i" -xdev -maxdepth 100 -type f | wc -l;  done
Reinstate Monica Please
  • 11,123
  • 3
  • 27
  • 48
0

Since find can take multiple paths, you don't need a loop:

find /home/*/ -xdev -maxdepth 100 -type f | wc -l

To avoid any issues with filenames containing newlines (rare, yes), you can take advantage of an additional GNU extension to find (you're using -maxdepth, so I assume you can use -printf as well):

find /home/*/ -xdev -maxdepth 100 -type f -printf "." | wc -c

Since you aren't actually using the name of the file for counting, replace it with a single-character string, then count the length of the resulting string.

chepner
  • 497,756
  • 71
  • 530
  • 681