A common problem I’ve come across in bash is that there doesn’t seem to be a way to check for the existence of multiple files in a directory. If you wanted to find out whither a particular file exists you could do the following:
#!/bin/bash if [ -e ~/files/x.txt ];then echo "Found file" else echo "Did not find file" fi
me@pc:~$ if [ -e ~/files/x.txt ];then echo "Found file";else echo "Did not find file";fi Did not find file me@pc:~$ echo hello > files/x.txt me@pc:~$ if [ -e ~/files/x.txt ];then echo "Found file";else echo "Did not find file";fi Found file me@pc:~$
See http://www.faqs.org/docs/bashman/bashref_68.html
No problem there. OK now let’s try and do that using a wild card
#!/bin/bash if [ -e ~/files/* ];then echo "Found file" else echo "Did not find file" fi
me@pc:~$ rm files/* me@pc:~$ if [ -e ~/files/* ];then echo "Found file";else echo "Did not find file";fi Did not find file me@pc:~$ echo hello > files/x.txt me@pc:~$ if [ -e ~/files/* ];then echo "Found file";else echo "Did not find file";fi Found file me@pc:~$
Everything looks fine *until* there is more than one file that meets the test criteria.
me@pc:~$ echo hello > files/y.txt me@pc:~$ if [ -e ~/files/* ];then echo "Found file";else echo "Did not find file";fi bash: [: /home/me/files/x.txt: binary operator expected Did not find file me@pc:~$
So what’s happening ? Well bash is expecting only one item in the search criteria so it bombs out. How I got around this was to run a ls command using the same glob and ignore the output by redirecting both the standard output and standard error to /dev/null
ls -1 ~/files/* > /dev/null 2>&1 if [ "$?" = "0" ]; then echo "Found file" else echo "Did not find file" fi
So let’s try it.
me@pc:~$ rm files/* me@pc:~$ ls -1 ~/files/* > /dev/null 2>&1; if [ "$?" = "0" ]; then echo "Found file"; else echo "Did not find file";fi Did not find file me@pc:~$ echo hello > files/x.txt me@pc:~$ ls -1 ~/files/* > /dev/null 2>&1; if [ "$?" = "0" ]; then echo "Found file"; else echo "Did not find file";fi Found file me@pc:~$ echo hello > files/y.txt me@pc:~$ ls -1 ~/files/* > /dev/null 2>&1; if [ "$?" = "0" ]; then echo "Found file"; else echo "Did not find file";fi Found file me@pc:~$
EDIT: Unescaped the html
Tags: bash multiple file
Thanks – just the thing
Thanks, just what I was looking for.
Tricky thing, the wildcard check
doe not work if there are *many* files matching…
if ls gives an ‘Argument list too long’, this behaves like there were no matches
You need to unescape your html entities!
Thanks Joe.
paul… if you have that many files in a directory, you probably need to use find and xargs.
The problem that I’m having is that I only want to find files in the current directory, and I don’t want the ‘ls’ to return true if a sub-directory exists. I’m thinking that my best bet is to use find in this case as well:
if [ $(find . -maxdepth 1 -type f | wc -l) == "0" ]
then echo “no files”
else echo “files exist”
fi
function exists {
for x in $*; do
test -e “$x” && return 0;
done
return 1
}
# THEN #
if exists foo*; then echo foostar exists; fi