views:

121

answers:

5

Hello all,

I am trying to list all directories and place its number of files next to it.

I can find the total number of files ls -lR | grep .*.mp3 | wc -l. But how can I get an output like this:

dir1 34 
dir2 15 
dir3 2 
...

I don't mind writing to a text file or CSV to get this information if its not possible to get it on screen.

Thank you all for any help on this.

+1  A: 

There's probably much better ways, but this seems to work.

Put this in a shell script:

#!/bin/sh
for f in *
do
  if [ -d "$f" ]
  then
      cd "$f"
      c=`ls -l *.mp3 2>/dev/null | wc -l`
      if test $c -gt 0
      then
          echo "$f $c"
      fi
      cd ..
  fi
done
Jon
Awesome! This was the best answer for me as it allowed me to add a comma in between the dir and the number easily so I can use it as a CSV file to view in excel and to also have it viewable on screen. Thank you jon. :)
Abs
+1  A: 
find . -type f -iname '*.mp3' -printf "%h\n" | uniq -c

Or, if order (dir-> count instead of count-> dir) is really important to you:

find . -type f -iname '*.mp3' -printf "%h\n" | uniq -c | awk '{print $2" "$1}'
Wrikken
+1 Works great.
Abs
Without a `sort` it can list some directories multiple times. Your awk command can be simplified to `awk '{print $2, $1}'` or you can do the OP's comma-delimited style like this: `awk '{print $2","$1}'`
Dennis Williamson
+3  A: 

This seems to work assuming you are in a directory where some subdirectories may contain mp3 files. It omits the top level directory. It will list the directories in order by largest number of contained mp3 files.

find . -mindepth 2 -name \*.mp3 -print0| xargs -0 -n 1 dirname | sort | uniq -c | sort -r | awk '{print $2 "," $1}'

I updated this with print0 to handle filenames with spaces and other tricky characters and to print output suitable for CSV.

Peter Lyons
+1 Works great.
Abs
I get an extra count for `.` unless I do `xargs -I{} -n 1 dirname \{\}`
Dennis Williamson
What OS and version of find do you have? The -mindepth 2 is supposed to eliminate `.`. I'm running Ubuntu 10.04 GNU find 4.4.2. This command does not include `.` for me. I tested with and without mp3 files in `.`
Peter Lyons
A: 

With Perl:

perl -MFile::Find -le'
  find { 
    wanted => sub {
      return unless /\.mp3$/i;
      ++$_{$File::Find::dir};
      }
    }, ".";
  print "$_,$_{$_}" for 
    sort { 
      $_{$b} <=> $_{$a} 
      } keys %_;
  '
radoulov
A: 

Here's yet another way to even handle file names containing unusual (but legal) characters, such as newlines, ...:

# count .mp3 files (using GNU find)
find . -xdev -type f -iname "*.mp3" -print0 | tr -dc '\0' | wc -c

# list directories with number of .mp3 files
find "$(pwd -P)" -xdev -depth -type d -exec bash -c '
  for ((i=1; i<=$#; i++ )); do
    d="${@:i:1}"
    mp3s="$(find "${d}" -xdev -type f -iname "*.mp3" -print0 | tr -dc "${0}" | wc -c )"
    [[ $mp3s -gt 0 ]] && printf "%s\n" "${d}, ${mp3s// /}"
  done
' "'\\0'" '{}' +
guzzo