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…
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.)