views:

226

answers:

5

Hi

I coded the below code and if no -l or -L option is passes to the script I need to assume (detect) whether a filename was passed as a param. The below third condition only matches if filename is one lowercase character. How can I make it flexible to match upper and lower case letters or variable length of the string?

while [ $# -gt 0 ]
    do

     case $1 in
      -l)     echo ls;;
      -L)     echo ls -l;;
      [a-z]) echo filename;;
      *) echo usage
       exit 1;;
     esac

     shift
    done

Also, how can I include a condition in that case statement that would react to empty $1? If for example the script is called without any options or filenames.

+2  A: 

You can match an empty string with a '') or "") case.

A file name can contain any character--even weird ones likes symbols, spaces, newlines, and control characters--so trying to figure out if you have a file name by looking for letters and numbers isn't the right way to do it. Instead you can use the [ -e filename ] test to check if a string is a valid file name.

You should, by the way, put "$1" in double quotes so your script will work if the file name does contain spaces.

case "$1" in
    '')     echo empty;;
    -l)     echo ls;;
    -L)     echo ls -l;;
    *)      if [ -e "$1" ]; then
                echo filename
            else
                echo usage >&2  # echo to stderr
                exit 1
            fi;;
esac
John Kugelman
"to check if a string is a valid file name" - actually it checks whether the file exists (as does `-e`)
Dennis Williamson
what's the difference between -e and -f then?
goe
See `man bash`: -e checks that a file exists, -f checks that it's also a file (not a directory)
John Kugelman
+1  A: 

Use getopts to parse options, then treat remaining non-option arguments however you like (such as by testing if they're a file).

Roger Pate
A: 

you find the information in the bash man page if you search for "Pattern Matching" without the quotes.this does the trick: [a-zA-Z0-9]*) you should probably read on about pattern matching, regular expressions and so on. furthermore you should honour john kugelmans hint about the double quotes. in the following code snippet you can see how to check if no parameter got passed.

#!/bin/sh

case "$1" in
    [a-zA-Z0-9]*)
     echo "filename"
    ;;
    "")
     echo "no data"
    ;;

esac
fin
A: 

@OP, generally if you are using bash, to match case insensitivity you can use shopt and set nocasematch

$ shopt -s nocasematch

to check null in your case statement

case "$var" in
  "") echo "empty value";;
esac
A: 

You are better off falling into the default case *) and there you can at least check if the file exists with [ -e "$1" ] ... if it doesn't then echo usage and exit 1.

prime_number