Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Path is added multiple times to result array unexpectedly

I am on macOS, and for the sake of being able to debug with VS Code, I installed bash 4 via homebrew.

I am developing a script that is supposed to result in an array of all files of a certain path.

My issue is that with a certain folder tree I am testing it, one file 3 levels deep gets added 4 times even though it exists only once. I am sure I am overlooking something that I cannot see…

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here’s the tree

.
├── fetchProjects.sh
├── foo
│   └── bar
│       └── buzz
│           └── foo.file
├── test1
└── test2

Here’s the script …:

#!/opt/homebrew/bin/bash

declare -a files=()

fetch_folder_content () {
    echo "Current path is: $1"
    subfolders="$(ls $1)"
    echo "Relative paths are: $subfolders"
    for subfolder in $subfolders; do
        declare -a subfolders=()
        this_path="$1/$subfolder"
        echo "This path: $this_path"
        if test -d $this_path; then
            fetch_folder_content $this_path
        fi
        if test -f $this_path; then
            echo "Appending $subfolder
     to array"
            files[${#files[@]}]=$this_path
        fi
    done
}

fetch_folder_content "."

echo "Found files:"
for file in "${files[@]}"; do
    echo "$file"
done

… resulting in the following array:

Found files:
./fetchProjects.sh
./foo/bar/buzz/foo.file
./foo/bar/buzz/foo.file
./foo/bar/buzz/foo.file
./foo/bar/buzz/foo.file
./test1
./test2

>Solution :

Use the globstar option to recursively walk a directory.

shopt -s globstar

files=()

for f in ./**/*; do
    test -f "$f" && files+=("$f")
done

As you are on macOS, if you use zsh instead, you can filter non-regular files using the glob directory (and you don’t need to explicitly enable the recursive glob **):

files=(./**/*(.))

(This applies to any machine with zsh installed; I only point out macOS because zsh has been the default interactive shell for years.)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading