2
recursiveprint() {
#FILES_COUNT=0

cd $1
  for d in *; do
    if [ -d "$d" ]; then
       (recursiveprint "$d")
    fi
    if [ -f "$d" ]; then
       file_name=$(basename "$d")
        ((FILES_COUNT++))
        clear
        echo  "$file_name"
        echo "total count = $FILES_COUNT"
    fi
    done
}
recursiveprint ${START_DIR}

The issue is, once it goes through one folder, it sets the count back to zero before iterating through another folder. Altogether, I have 30 files in different folders, the count ends up being 6 i.e the number of files in the last folder it iterates through. Any tips on how to solving this?

3 Answers 3

5
if [ -d "$d" ]; then
   (recursiveprint "$d")
fi

The parenthesis surrounding the line (recursiveprint "$d") run the function in a subshell. When the subshell starts, the value of FILES_COUNT is cloned, and changes made in the recursive call within the subshell don't take effect in the surrounding environment.

Without a subshell, it should work better, but then you need to manually go back to the parent directory when returning from an instance of the function. cd .. would do for the calls made within the function, but let's use a variable so we can go back to the original working directory, even if it's given as an absolute path.

recursiveprint() {
    local oldpwd=$PWD
    cd "$1"
    ...
        if [ -d "$d" ]; then
           recursiveprint "$d"          # no parenthesis here
        fi
    ...
    cd "$oldpwd"
}

Also note that * doesn't match filenames starting with a dot by default, use shopt -s dotglob, if you want it to.

6
  • My understanding of Bash is only decent so please do bear with me.Upon amending the script file, the $oldpwd is only echoing the last folder with the # of file(s) in it,not the total files in the whole directory (30). Here is the amended script file: Commented May 15, 2017 at 12:33
  • #!/usr/bin/env bash START_DIR="/tmp/shakapaka" #FILES_COUNT=0 recursiveprint() { local oldpwd=$PWD cd $1 for d in *; do if [ -d "$d" ]; then (recursiveprint "$d") fi if [ -f "$d" ]; then #((++FILES_COUNT)) file_name=$(basename "$d") clear echo "$file_name" echo "total count = $oldpwd" fi done } recursiveprint ${START_DIR} Commented May 15, 2017 at 12:34
  • @Raphael, it's the parenthesis that start the subshell, you still have them in that snippet. Commented May 15, 2017 at 12:47
  • When I take off the parenthesis, it comes up with an error: fileshaka.sh: line 20: syntax error near unexpected token }' fileshaka.sh: line 20: }' [root@crap01 shakapaka]# Commented May 15, 2017 at 13:11
  • Currently have this: #!/usr/bin/env bash START_DIR="/tmp/shakapaka" #FILES_COUNT=0 recursiveprint{ local oldpwd=$PWD cd $1 for d in *; do if [ -d "$d" ]; then (recursiveprint "$d") fi if [ -f "$d" ]; then #((++FILES_COUNT)) file_name=$(basename "$d") clear echo "$file_name" echo "total count = $oldpwd" fi done } recursiveprint $START_DIR Commented May 15, 2017 at 13:12
3

Won't

find /my/dir/ -type f | grep -c .

work for you?

0
2
find .// -type f | grep -c '^\.//'

will count all files reliably (even those that comprise newlines in their names).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.