6

The following bash snippet works great when there are actually *.txt files in the directory.

for txt in *.txt
do                                               
  echo "loading data from $txt"
done   

When there aren't, the literal *.txt falls into the loop as $txt (not good).

How do I change this code so that when there are no *.txt files, the do ... done block is skipped?

  • 1
    if [ "*.txt" != '*.txt' ] ; then do loop here ; fi – ott-- Dec 14 '12 at 14:08
  • @ott-- +1 for offering an alternative solution – kfmfe04 Dec 14 '12 at 14:36
  • 1
    @ott: [ "*.txt" != '*.txt' ] is always false -- both strings are in quotes, so neither gets checked for matches. If you remove the quotes from one it ... has other problems. – Gordon Davisson Dec 14 '12 at 19:47
  • @GordonDavisson +1 for pointing this out: shell scripting seems to be full of surprises... – kfmfe04 Dec 14 '12 at 20:05
  • 1
    @GordonDavisson Indeed, it must be done in 2 steps to work: files=$(echo *.txt) and then: if [ "${files}" != '*.txt' ] ; then. – ott-- Dec 15 '12 at 14:17
9

Looks like google had the answer to this one.

Put this magic incantation before the for statement:

shopt -s nullglob
  • Be aware that this may cause surprise side effects on commands like "ls *.txt" – noonex Feb 5 at 14:47
4

The nullglob option (@kfmfe04's answer) is best if you are using bash (not a brand-X shell), and don't have to worry about nullglob changing/breaking anything else. Otherwise, you can use this (slightly messier) option:

for txt in *.txt
do
  [ -e "$txt" ] || continue
  echo "loading data from $txt"
done

This silently skips files that don't exist (mainly "*.txt" if there were no matches, but possibly also files that were deleted between when the for generated the list and when the loop got to them...)

  • A file might be deleted between -e invocation and later processing still... – Koterpillar Sep 25 '18 at 2:01
  • @Koterpillar True, but testing -e reduces the time window where deletion is a problem. – Gordon Davisson Sep 25 '18 at 2:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.