The problem you are having is that after you cd "$dir"
the first time, you are one directory below where you generated your list of directories with for dir in */
. So the next time you call cd "$dir"
it fails because you are still in the first subdirectory you cd
'ed into and the next "$dir"
in your list is one level above.
There are several ways to handle this. One simple one is to use pushd
to change to the directory instead of cd
, so you can popd
and return to your original directory. (though in this case you could simply add cd ..
to change back to the parent directory since you are only one-level deep)
Using pushd/popd
you could do:
for dir in */; do
echo $dir
pushd "$dir" &>/dev/null || {
printf "error: failed to change to %s\n" "$dir" >&2
continue
}
cwd="$PWD"
mkdir -p "VSI" || {
printf "error: failed to create %s\n" "$cwd/VSI" >&2
continue
}
mv -v *.vsi "$cwd/VSI"
mv -v _*_ "$cwd/VSI"
popd &>/dev/null || {
printf "error: failed to return to parent dir\n" >&2
break
}
done
(note: the ||
tests validate the return of pushd, mkdir, popd
causing the loop to either continue to the next dir or break the loop if you can't return to the original directory. Also note the &>/dev/null
just suppresses the normal output of pushd/popd
, and redirection of output to >&2
sends the output to stderr
instead of stdout
)
As mentioned in the comment, you can always use readlink -f "$dir"
to generate the absolute path to "$dir"
-- though it's not really needed here.