searching if the file exists

Hi All,

I want to search multiple files but i dont know their exact names

ls -ltr a*
a1.240410
a2.240410
a3.240410
a4.240410

these file names keep changing acco to date or randomly

so I wanna check if any file with a* exists and then perform an actiion

I was trying

 
if [ -e "a*" ]; then
....
..
fi

but looks like with if i hav to give complete file name like
if [ -e a1.240410 ]

please help.. I wanna check if a* files exist . thanks!

---------- Post updated at 09:52 AM ---------- Previous update was at 09:45 AM ----------

Also if i try to do ls -ltr a* and if no files exist then i dont want any error like " no such file or directory"

like

(ODS:prd)/home/r104809> ls -ltr proc* | wc -l
proc*: No such file or directory
0

I dont want this error I just need the count 0

what change will help me?
Thanks guys!!

if ls a* > /dev/null 2>&1; then
  echo "files exist"
else
  echo "files do not exist"
fi
for FILE in a*
do 
  ls -l $FILE
  strings $FILE
  . . .
done

masta
Why scottn is right and you are not ?

No person is wrong.

Scottn's solution is, in my personal opinion, not as ideal as my own proposal.

The reason is that Scottn's solution requires to invoke `ls -l`, where mine uses pure shell globs. I see no reasons to venture outside the capability of the shell. There is no reason to test for the existence of the files when a pattern-match (glob) will reveal their existence. No reason to see if the ls command returns true... it's a waste of time

have a nice day

What is wrong with this?

$ [ -f m* ] && echo "file exists" || echo "file does not exist"
file exists
$ [ -f a* ] && echo "file exists" || echo "file does not exist"
file does not exist

I am able to check for any files using wild cards as you asked for using the -f (exists and is a file) and -e (exists).

Why do you think this does not work?

Also to add to the example masta gives:

for F in m*
do
    # Gather a list of files for use later
    FILES="${FILES} ${F}"
    # or you can simply preform actions here on each
    # individual file
done

# The variable FILES will either be empty or have a list of files you asked for
# If nothing matches m* then it is empty

echo "${FILES}" # or use the var FILES as needed.
# While '/bin/echo' exists echo is also built-in in bash and sh. 
# Since we give no path echo is overridden here.
# man bash and look under 'SHELL BUILTIN COMMANDS'

I am using 100% pure shell globs and built-ins and no external calls this way.

masta, you make good point however you do use an external invoke of "ls -l" and "strings" and you do it multiple times (1 for each file) whereas scottn only makes the call once.
The difference here is presumably meant to imply "only in your initial check for existence of the files" and that what you do "with" these files once found is another matter. We can't use built-ins for everything after all :slight_smile:

I just meant to add that it may seem confusing to new script writers if the distinction is not made.

for FILE in a*    # Pure shell glob here but...
do 
  ls -l $FILE       # This is just as much of an external call as scottn does!
  strings $FILE
  . . .
done

I do however tend to agree with what masta means to show you, scottn has a valid working solution however we should (in my opinion) try to use the built-in functions of the shell we are in if external applications (ls in scottn's case) is not needed.

Now again this is a personal preference and scottn's method does have an advantage in one case. If the built-ins we rely on are shell specific (example: parameter expansion, let, set, unset, export, pushd, popd) then we cannot port this script in it's raw form to another shell (ie from bash to ksh/csh/sh). In this case using the external "ls" and "echo" commands means that we can use this script in any shell that can find the ls command in it's path!

Your assumption about FILE being empty if there are no matching files is incorrect. Shell globs that do not match anything do not simply disappear, or expand to nothing; they remain unexpanded, and the for loop's list will be that single value.

Test run:

$ for F in m*; do echo "$F"; done
m*

That code, and masta's solution, will both execute the loop at least once. If that is undesirable, the existence of the value in F must be tested; it cannot be taken for granted.

Regards,
Alister

ahh yes good point. Thanks alister for pointing that out.