Test whether a glob has any matches in bash

后端 未结 19 2334
夕颜
夕颜 2020-11-22 15:51

If I want to check for the existence of a single file, I can test for it using test -e filename or [ -e filename ].

Supposing I have a glob

相关标签:
19条回答
  • 2020-11-22 16:32
    set -- glob*
    if [ -f "$1" ]; then
      echo "It matched"
    fi
    

    Explanation

    When there isn't a match for glob*, then $1 will contain 'glob*'. The test -f "$1" won't be true because the glob* file doesn't exist.

    Why this is better than alternatives

    This works with sh and derivates: ksh and bash. It doesn't create any sub-shell. $(..) and `...` commands create a sub-shell; they fork a process, and therefore are slower than this solution.

    0 讨论(0)
  • 2020-11-22 16:34

    Like this in bash (test files containing pattern):

    shopt -s nullglob
    compgen -W *pattern* &>/dev/null
    case $? in
        0) echo "only one file match" ;;
        1) echo "more than one file match" ;;
        2) echo "no file match" ;;
    esac
    

    It's far better than compgen -G: because we can discriminates more cases and more precisely.

    Can work with only one wildcard *

    0 讨论(0)
  • 2020-11-22 16:36

    I have yet another solution:

    if [ "$(echo glob*)" != 'glob*' ]
    

    This works nicely for me. Are there some corner cases I miss?

    0 讨论(0)
  • 2020-11-22 16:36

    ls | grep -q "glob.*"

    Not the most efficient solution (if there's a ton of files in the directory it might be slowish), but it's simple, easy to read and also has the advantage that regexes are more powerful than plain bash glob patterns.

    0 讨论(0)
  • 2020-11-22 16:37

    test -e has the unfortunate caveat that it considers broken symbolic links to not exist. So you may want to check for those, too.

    function globexists {
      test -e "$1" -o -L "$1"
    }
    
    if globexists glob*; then
        echo found
    else
        echo not found
    fi
    
    0 讨论(0)
  • 2020-11-22 16:40
    #!/usr/bin/env bash
    
    # If it is set, then an unmatched glob is swept away entirely -- 
    # replaced with a set of zero words -- 
    # instead of remaining in place as a single word.
    shopt -s nullglob
    
    M=(*px)
    
    if [ "${#M[*]}" -ge 1 ]; then
        echo "${#M[*]} matches."
    else
        echo "No such files."
    fi
    
    0 讨论(0)
提交回复
热议问题