Check and control params in parsing file

Hello,

I would like to control and check the right parameters
$1 must have 4 alphabetics digits among eora qora pora fora
$2 must have 2 numerics digits 00 to 11
$3 must have 2 numerics digits 00 to 59
$4 must have 10 characters alpha numerics as 2013-02-26

For example :
In case 5) if i launch my script with these parameters

./my_script dora 09 30 2013-02-26

The first parameter dora is bad, i would like that the script returns "The first parameter dora is bad"
and so on.
Can you give me some advices ?
Thank you

#!/bin/bash
# set -vx

f1()    {
         echo $1 $2 $3 $4                                       # put your function here
        }


case $# in
        0)      echo -e "# comment1\n# comment2" > list_file    # create list_file as desired
                read -p "Please fill in this list_file: "       # prompt as desired, read answer
                echo $REPLY                                     # do whatever with the user's reply
                ;;
        1)      [ -f "$1" ] || exit                             # check if file exists; otherwise exit
                grep -v '^#' "$1" |                             # do what you did before
                        while read arg1 arg2 arg3 arg4
                                do f1 $arg1 $arg2 $arg3 $arg4
                                done
                ;;
        4)      echo -e "# comment1\n# comment2" > list_file    # create list_file as desired
                echo $1 $2 $3 $4 >> list_file                   # put your function here
                ;;
        5)      echo -e "# comment1\n# comment2" > $1           # create file with $1 file name as desired
               f1 $1 $2 $3 $4 >> "$1"                   # put your function here
                ;;

        *)      echo "error msg"; exit
esac

Doesn't bash do full regex matching in:

$ bash -c 'if [[ 99 == '[0-9][0-9]' ]] ; then echo true ; fi'
true
$

No. It is using filename pattern matching. Try:

bash -c 'if [[ 9a9 == '[0-9].[0-9]' ]] ; then echo true ; fi'

and

bash -c 'if [[ 9a9 == '[0-9]?[0-9]' ]] ; then echo true ; fi'
true

---------- Post updated at 10:37 ---------- Previous update was at 10:23 ----------

Is this a homework item? If so, this is the wrong forum.
Note: "-" is not an alphanumeric character. It is a punctuation character.

File glob == is nice, but regex =~ is nicer!

$ bash -c 'if [[ 99 =~ '[0-9]\{2\}' ]] ; then echo true ; fi'
true
$

Hello,
Here my new modifed script.
I only verify the first parameter in the inputfile named list_file

$ cat list_file
# comment1
# comment2
dora B C D

When i launched

./my_script list_file
bad argument

there would have

./my_script list_file

Thanks in advance for your help.

dora B C D
#!/bin/bash
# set -vx

f1()    {
      bash -c 'if [[ "$arg1" =~ '^\{d,q,p,f}ora' ]]; then
       echo $1 $2 $3 $4
      else echo "bad argument";
       fi'
        }
case $# in
        0)      echo -e "# comment1\n# comment2" > list_file
                read -p "Please fill in this list_file: "
                echo $REPLY
                ;;
        1)     if [ ! -f "$1" ]
               then  > $1 && echo -e "# comment1\n# comment2" > $1
               read -p "Please fill in "$1": "
               echo $REPLY
               else
                   if [ -f "$1" -a $(grep -v '^#' "$1" | wc -l ) -ne 0 ]
                   then
                   grep -v '^#' "$1" |
                        while read arg1 arg2 arg3 arg4
                                do f1 $arg1 $arg2 $arg3 $arg4
                                done
                   else
                   read -p "Please fill in $1 : "
                   echo $REPLY
                   fi
               fi
               ;;
        4)      echo -e "# comment1\n# comment2" > list_file
                echo $1 $2 $3 $4 >> list_file
                ;;
        5)      echo -e "# comment1\n# comment2" > $1
                f1 $2 $3 $4 $5 >> "$1"
                ;;

        *)      echo "error msg"; exit
esac

You're not running bash within bash to do that parameter check, are you? And you know, that single quotes within single quotes don't work?
And, I have to admit, even though I gave you the first hints on that script snippet, I'm totally lost now trying to read and understand what you are aiming for.
Would you mind to present - in plain words - what the target of your script is?

Thank you RudiC,
I'm learning scripting, I want increase the robustness of the script.
There, i want to control each parameters entered by the user in the input file.
$1 must have 4 alphabetics digits like eora qora pora fora
$2 must have 2 numerics digits 00 to 11 (hours)
$3 must have 2 numerics digits 00 to 59 (minutes)
$4 must have 10 characters alpha numerics and ponctuations as 2013-02-26
./my_script dora 09 30 2013-02-26

I used to take this script in order to test for example regular expressions, certains conditions etc... Then i can implement them in others scripts.
I hope I was clear Mister RudiC. I learn a lot with you.

This sound like a school class project.
Post real data, what you have and then post example output.
Then add a good description on how you came to this output.

Eks: I have two value and like to add them together into a new variable.

Data

A=5
B=6

Requested output

C=11

Hello,
It's not, nor a school class project nor a homework item.
I'm a scripting self-didact for my job.
It is necessary that I start at the beginning. I learn by example.
Like building a house, brick by brick, I build my script.
This is a generic script, it may be useful to other people.
In my case, I use it to retrieve a piece of log, that's why I put the following parameters: start time, end time, date etc.
Instead of the function f1, you can put your own function.
To be clearer, my function f1 is a simple echo " ". Here, the main problem is how do i do to control the parameters which i put in the input file ?

Thank you for your help.

---------- Post updated at 01:08 AM ---------- Previous update was at 12:40 AM ----------

I would like my function f1 detect that in the fifth line, the first parameter is an error. And the script must return 'bad argument".
If it can return "The 1st argument in the $line is wrong" it would be better. But perhaps this is asking too much.
Alone, I turn around. With you, I learn faster.
Sorry for my broken English.
Thanks you

vi list_file
dora B C D
qora B C D
pora B C D
fora B C D
aaaa B C D
vi my_script.sh
#!/bin/bash
# set -vx

f1()    {
      if [[ "$arg1" =~ '^\{d,q,p,f}ora' ]]; then
       echo $1 $2 $3 $4
      else echo "bad argument";
       fi
        }
case $# in
        0)      echo -e "# comment1\n# comment2" > list_file
                read -p "Please fill in this list_file: "
                echo $REPLY
                ;;
        1)     if [ ! -f "$1" ]
               then  > $1 && echo -e "# comment1\n# comment2" > $1
               read -p "Please fill in "$1": "
               echo $REPLY
               else
                   if [ -f "$1" -a $(grep -v '^#' "$1" | wc -l ) -ne 0 ]
                   then
                   grep -v '^#' "$1" |
                        while read arg1 arg2 arg3 arg4
                                do f1 $arg1 $arg2 $arg3 $arg4
                                done
                   else
                   read -p "Please fill in $1 : "
                   echo $REPLY
                   fi
               fi
               ;;
        4)      echo -e "# comment1\n# comment2" > list_file
                echo $1 $2 $3 $4 >> list_file
                ;;
        5)      echo -e "# comment1\n# comment2" > $1
                f1 $2 $3 $4 $5 >> "$1"
                ;;

        *)      echo "error msg"; exit
esac

For the function in magenta, do you want to test arg1 (a global variable inherited from the main, not necessarily set), or $1 (the first parameter in the function call). If $1, try

[[ "$1" =~ [dqpf]ora ]] && echo $1 $2 $3 $4 || echo "bad argument"

Still you did not answer my question for an overall description in plain english: I can see that one of the goals is a file consisting of two comment lines, and then data lines starting with [dqpf]ora . But the several starting points, those that you are coming from, are highly obscured. Coming back to your brick laying example, it's wise to start with the fundament, but my impression from your fundament is your building will be a maze.

I want to test global variables $arg
Excuse me i have a mistake it would be 23 instead of 11
I would like to control and check the right parameters
$1 must have 4 alphabetics digits among eora qora pora fora
$2 must have 2 numerics digits 00 to 23 (hours)
$3 must have 2 numerics digits 00 to 59 (minutes)
$4 must have 10 alpha numerics and ponctuations characters as 2013-02-26

RudiC, i follow yours instructions

vi my_script.sh
#!/bin/bash
# set -vx

f1()    {
       [[ "$arg1" =~ [dqpf]ora ]] && echo $arg1 $arg2 $arg3 $arg4 || echo "bad argument"
        }
case $# in
        0)      echo -e "# comment1\n# comment2" > list_file
                read -p "Please fill in this list_file: "
                echo $REPLY
                ;;
        1)     if [ ! -f "$1" ]
               then  > $1 && echo -e "# comment1\n# comment2" > $1
               read -p "Please fill in "$1": "
               echo $REPLY
               else
                   if [ -f "$1" -a $(grep -v '^#' "$1" | wc -l ) -ne 0 ]
                   then
                   grep -v '^#' "$1" |
                        while read arg1 arg2 arg3 arg4
                                do f1 $arg1 $arg2 $arg3 $arg4
                                done
                   else
                   read -p "Please fill in $1 : "
                   echo $REPLY
                   fi
               fi
               ;;
        4)      echo -e "# comment1\n# comment2" > list_file
                echo $1 $2 $3 $4 >> list_file
                ;;
        5)      echo -e "# comment1\n# comment2" > $1
                f1 $2 $3 $4 $5 >> "$1"
                ;;

        *)      echo "error msg"; exit
esac
cat list_file
# comment 1
# comment 2
# here all parameters are right
dora 02 15 2013-03-03
qora 03 59 2013-02-08
pora 11 00 2012-12-31
dora 00 00 2013-01-01
# here all parameters are wrong
cora 25 60 2013/01/01
./my_script list_file
dora 02 15 2013-03-03
qora 03 59 2013-02-08
pora 11 00 2012-12-31
dora 00 00 2013-01-01
bad argument

It's OK for the first parameter [dqpf]ora ]
Can we put the line number ?

For the others parameters, i tried to test them in vain.

This time i hope to be clear.
Thanks

Again, be aware that arg n may NOT be set!
Add this to your f1 function for testing the other parameters:

[[ "$2" -ge "0" && "$2" -le "23" ]] && echo \$2 is good || echo \$2 is bad
[[ "$3" -ge "0" && "$3" -le "59" ]] && echo \$3 is good || echo \$3 is bad
[[ "$4" =~ [0-9]{4}-[0-9]{2}-[0-9]{2} ]] && echo \$4 is good || echo \$4 is bad
$ ./test a  1 34 2013-03-03
$2 is good
$3 is good
$4 is good
$ ./test a  24 69 201-03-03
$2 is bad
$3 is bad
$4 is bad

Why, then, do you call f1 like you do: f1 $arg1 $arg2 $arg3 $arg4

---------- Post updated at 13:24 ---------- Previous update was at 13:06 ----------

Put this into your f1 function:

echo -n "line $5: \$1 is "; [[ "$1" =~ [dqpf]ora ]] && echo good || echo bad
echo -n "line $5: \$2 is "; [[ "$2" -ge "0" && "$2" -le "23" ]] && echo good || echo bad
echo -n "line $5: \$3 is "; [[ "$3" -ge "0" && "$3" -le "59" ]] && echo good || echo bad
echo -n "line $5: \$4 is "; [[ "$4" =~ [0-9]{4}-[0-9]{2}-[0-9]{2} ]] && echo good || echo bad

and call it like

$ while read a1 a2 a3 a4; do f1 $a1 $a2 $a3 $a4 $((++line)); done < file
line 1: $1 is good
line 1: $2 is good
line 1: $3 is good
line 1: $4 is good
line 2: $1 is good
line 2: $2 is good
line 2: $3 is bad
line 2: $4 is good
line 3: $1 is good
line 3: $2 is bad
line 3: $3 is good
line 3: $4 is good
line 4: $1 is bad
line 4: $2 is good
line 4: $3 is good
line 4: $4 is good

Be aware that your grep ing out comments will render the line no. incorrect, so you need to take action there. I guess, from the course of this thread, it will be us who need to take the action...

AND, this thread is applying band aid after band aid after band aid as you DO NOT clearly present your objectives. Planning upfront makes a good program!

1 Like

Thanks a lot RudiC :slight_smile:
I'm going to take time to think about your code.
I'll be back later.

'case' is the oldest, most portable pattern check. Use (..) on patterns so vi's '%' can track/traverse them:

case "$1" in
([a-z][a-z][a-z][a-z])
  # nothing, OK !
  ;;
(*)
  echo 'Fatal, $1 = '"'$1'"', is not 4 lower case alpha.' >&2
  exit 1
  ;;
esac
1 Like

Hello,
Thank you DGPickett,
It seems a good alternative, i'm going to test it.
What is the meaning of &2 ?

Write to stderr. Stdout is for data, stderr is for logging.