Recursive Function to Return Directory Depth of File Tree

I'm trying to write a function that will traverse the file directory and give me the value of the deepest directory. I've written the function and it seems like it is going to each directory, but my counter doesn't seem to work at all.

dir_depth(){ 

local olddir=$PWD
local dir
local counter=0
cd "$1"


for dir in *
do
  if [ -d "$dir" ]
  then
    dir_depth "$1/$dir"
    echo "$dir"
    counter=$(( $counter + 1 ))
  fi 
done
cd "$olddir"
}

What I want it to do is feed the function a directory, say /home, and it'll go down each subdirectory within and find the deepest value. I'm trying to learn recursion better, but I'm not sure what I'm doing wrong.

Answers


Here is a version that seems to work:

#!/bin/sh

dir_depth() {
  cd "$1"
  maxdepth=0
  for d in */.; do
    [ -d "$d" ] || continue
    depth=`dir_depth "$d"`
    maxdepth=$(($depth > $maxdepth ? $depth : $maxdepth))
  done
  echo $((1 + $maxdepth))
}

dir_depth "$@"

Obviously find should be used for this

find . -type d -exec bash -c 'echo $(tr -cd / <<< "$1"|wc -c):$1' -- {} \;  | sort -n | tail -n 1 | awk -F: '{print $1, $2}'

At the end I use awk to just print the output, but if that were the output you wanted it would be better just to echo it that way to begin with.

Not that it helps learn about recursion, of course.


Just a few small changes to your script. I've added several explanatory comments:

dir_depth(){

    # don't need olddir and counter needs to be "global"
    local dir
    cd -- "$1"    # the -- protects against dirnames that start with -

    # do this out here because we're counting depth not visits
    ((counter++))

    for dir in *
    do
      if [ -d "$dir" ]
      then
        # we want to descend from where we are rather than where we started from
        dir_depth "$dir"
      fi
    done
    if ((counter > max))
    then
        max=$counter      # these are what we're after
        maxdir=$PWD
    fi
    ((counter--))    # decrement and test to see if we're back where we started
    if (( counter == 0 ))
    then
        echo $max $maxdir    # ta da!
        unset counter        # ready for the next run
    else
        cd ..   # go up one level instead of "olddir"
    fi
}

It prints the max depth (including the starting directory as 1) and the first directory name that it finds at that depth. You can change the test if ((counter > max)) to >= and it will print the last directory name it finds at that depth.


Need Your Help

How to save or storing the SKPayment transaction?

ios transactions save nsuserdefaults storekit

I would like to store the SKPayment transaction in the user defaults or on the device, and I also would like to store the transaction data on my server at a later date (not done yet) so that a user...

Creating an SQL query with multiple counts and different criteria from one table

sql vb.net vba ms-access

I have an Access DB I have coded in VBA which my team use to log all of our requests. I want to create a query which will pull multiple counts from a single table with different criteria. An exampl...