bash iterate file list, except when empty
In bash
, you can set the nullglob
option so that a pattern that matches nothing "disappears", rather than treated as a literal string:
shopt -s nullglob
for fname in *.zip ; do
echo "current file is ${fname}"
done
In POSIX shell script, you just verify that fname
exists (and at the same time with [ -f ]
, check it is a regular file (or symlink to regular file) and not other types like directory/fifo/device...):
for fname in *.zip; do
[ -f "$fname" ] || continue
printf '%s\n' "current file is $fname"
done
Replace [ -f "$fname" ]
with [ -e "$fname" ] || [ -L "$fname ]
if you want to loop over all the (non-hidden) files whose name ends in .zip
regardless of their type.
Replace *.zip
with .*.zip .zip *.zip
if you also want to consider hidden files whose name ends in .zip
.
export -f myshellfunc
find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec bash -c 'myshellfunc "$0"' {} \;
You MUST export your shell function with export -f
for this to work.
Now find
executes bash
which executes your shell function, and remains at the current dir level only.
set ./* #set the arg array to glob results
${2+":"} [ -e "$1" ] && #if more than one result skip the stat "$1"
printf "current file is %s\n" "$@" #print the whole array at once
###or###
${2+":"} [ -e "$1" ] && #same kind of test
for fname #iterate singly on $fname var for array
do printf "file is %s\n" "$fname" #print each $fname for each iteration
done
In a comment here you mention invoking a function...
file_fn()
if [ -e "$1" ] || #check if first argument exists
[ -L "$1" ] #or else if it is at least a broken link
then for f #if so iterate on "$f"
do : something w/ "$f"
done
else command <"${1-/dev/null}" #only fail w/ error if at least one arg
fi
file_fn *