I want to use something like find
to recursively find all subdirectories and I need to do so in a for
loop - the tasks are too complicated and long for &
's.
The above part is easy, but I also need it to include spaces and dots (prefixed) in the directory names - which so far I failed with every single solution I found on this SE. The names always either get split, or find
just spits out a single string ( for
loop happens only once).
For a pure Bash for
-loop, use this:
shopt -s nullglob globstar dotglob
for subdir in **/; do
do_stuff_with "$subdir" # quote the expansion "$subdir"
done
**/
with the shell option globstar
. dotglob
option asks the shell to also glob on “hidden” files (the ones that have a leading period). nullglob
is to have the glob expand to nothing when there are no matches. (It's always a good idea to use it when looping on globs; otherwise failglob
is a good choice when using a glob as argument to a command). With GNU find
you can also do it as follows (don't forget to use -print0
and use read
's delimiter option -d ''
, and also -r
, and an empty IFS
):
while IFS= read -r -d '' subdir; do
do_stuff_with "$subdir" # quote the expansion "$subdir"
done < <(find . \! -name . -type d -print0)
The \\! -name .
\\! -name .
predicate is to exclude the parent ./
directory.
Both methods are safe with respect to any funny symbols you will have in filenames provided you quote the expansion "$subdir"
!
But I guess that the main problem you encountered with spaces is that you didn't quote your variable expansions!
Don't forget to quote every single expansion
"$subdir"
.
Did I say that you should quote every single variable expansion?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.