Search code examples
bashglob

Test whether a glob has only one match in bash and get it


The question "Test whether a glob has any matches in bash" and it's answer is quite well.

But, I want to know how to test whether a glob has only one match in bash and if it exists assign to a variable.

How can I do it?


Solution

  • You do not need nullglob. With a simple test you can validate if your glob expanded to a single entry, or zero or more entries:

    globexpand=( globexpression )
    [[ -e "${globexpand[@]}" ]] && var="$globexpand"
    

    This works for the following reasons:

    1. if globexpression matches multiple files, the test with -e will fail
    2. if globexpression matches a single file, the test with -e will match
    3. if globexpression matches no file, the globexpand will hold the globexpression as a single entry and will fail the test with -e.

    So you do not need any nullglob or any special option. Just make sure you quote correctly here to handle filenames with special characters.

    An alternative way is to make use of find to count how many matches your glob has:

    $ find . -maxdepth 1 -name 'globexpr' -printf c | wc -c
    

    We make use of printf so that we do not have a problem with funny filenames which might contain a newline character. Having this said, it is now straightforward:

    if [[ $(find . -maxdepth 1 -name 'globexpr' -printf c | wc -c) == "1" ]]; then
        # do your magic
    else
        # do some other stuff
    fi