0

I am trying to write an if statement in shell combined with command last The if statement should check the output of command last and print only the lines of which month user chose. For example user input is: Mar January

Result should be: "Mar Good format" and print all the lines of the command last that have Mar as their month.

For January it should say: "January Bad format" and print nothing else.

This is the code so far:

echo "Enter the month name (acording to last command results format):"
read month month1
if [[ $month == [aA-zZ][aA-zZ][aA-zZ] ]]
then
echo "$month Good format"
else 
echo "$month Bad format"
fi

It only checks for one of the inputs and prints only for one input. I don't know how to check both of the strings in one if statement and print the results for both, if one fails and the other is correct.

5
  • Can you show us what you've tried so far and explain where you're having difficulties? Commented Apr 10, 2022 at 17:54
  • 1
    You'll want to read How do I ask a good question? and other Asking articles. Commented Apr 10, 2022 at 18:09
  • @larsks there i aded a code i have so far Commented Apr 10, 2022 at 18:12
  • Create a checkMonth function that accepts a single month. Then call that function for both month and month1. If your code will never ever read anything other than two words, then that's the end of it. If you code has to read an indeterminate number of words, then you'll probably want to read a string and parse it into a list of words and then iterate over the list. Commented Apr 10, 2022 at 18:17
  • @JeffHolt i think you read the problem wrong. If user input only 3 letters for example: Jan or Dec it should say that it's good format and if he input the full name of month then it prints that the format is bad Commented Apr 10, 2022 at 18:20

2 Answers 2

1

A variation of the solution offered by @Nic3500 that separates the empty string test and then uses the [[ ... ]] test for a substring match of the months passed to the function could be:

#!/bin/bash

check_month()
{
    [ -z "$1" ] && { echo "'' Bad format"; return 1; }
    
    valid_values=(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
    
    if [[ ${valid_values[@]} =~ $1 ]]
    then
        echo "$1 Good format"
    else
        echo "$1 Bad format"
    fi
}

for i in "$@"; do
    check_month "$i"
done

When using [[ ... ]] variable quoting isn't necessary, but does influence how the right side regex is evaluated.

Example Use/Output

The modified script above passes the command-line arguments of the script to the function to be checked, e.g.

bash chkmonths.sh Apr May June Jun July july Jul Dec foo
Apr Good format
May Good format
June Bad format
Jun Good format
July Bad format
july Bad format
Jul Good format
Dec Good format
foo Bad format

The array as a lookup proposed by @Nic3500 is a very good approach. Though when used with [[ ... ]] a simple space separated string of allowable names will work as well.

Sign up to request clarification or add additional context in comments.

1 Comment

is it better to add: last -n 30000 | grep "^$user" | grep pts | grep "$month" to the checking under the then statement or should i use awk better to sort the month
0

One way you could do that is:

#!/bin/bash

check_month()
{
    checkmonth="$1"
    valid_values=(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
    if [[ " ${valid_values[*]} " =~ " $checkmonth " && "$checkmonth" != '' ]]
    then
        echo "$checkmonth Good format"
    else
        echo "$checkmonth Bad format"
    fi
}

echo "Enter the month name (acording to last command results format):"
read -r month month1

check_month "$month"
check_month "$month1"
  • function check_month verifies the month received in argument.
  • the valid_values is an array of good values. Checking that the month value is three characters is not enough, since abc is not a valid month value.
  • the if checks if the value received by the function is somewhere in the array.
  • the if also verifies if the month value is empty, just in case your user types only 1 value (or no value at all).

7 Comments

Your regex matches if checkmonth is assigned to J , an or Fe... I would say something like valid_values='^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)$'; if [[ $checkmonth =~ $valid_values ]]; then ...
Thanks for pointing it out, my tests were too limited, and I wrongly copy-paste. I modified it.
Thank you for the prompt reply, but It still meets for checkmonth="Jan Feb". :)
If I run my script and input Jan Feb as answer for the read, I get "Jan Good format" and "Feb Good format".
I see. It is due to the word splitting of read builtin.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.