Grep statement in If-Then-Else Statment is not giving intended results

僤鯓⒐⒋嵵緔 提交于 2019-12-08 13:57:42

问题


The intended result of this program is to perform the deletion of a record from a temporary file by searching for the last name. If the name is in the file it will display a message that the record is deleted from the file. The message will have a last and first name of the person deleted. If there is no record for the name entered, display an error message indicating that the name is not in the file. The error message will have the last name of the person searched.

For the most part I have figured this code completely out. However, I am running into errors that are giving me a lot of trouble.

Code is as follows:

#While loop
            delete_choice="y"           
            until [[ $delete_choice == "n" ]]
            do
            #Create Delete Message
            clear
            echo "                                 Delete Record                                 "
            echo -en '\n'
            echo -en '\n'
            echo "What is the last name of the person you want to delete:"
            read last_name
            if line=$( grep -Fi "$last_name" "$2")
            then
            IFS=: read c1 c2 rest <<< "$line"
            echo -e "Last Name: $c1\nFirst Name: $c2\nSTUDENT RECORD HAS BEEN DELETED FROM FILE"
            sed "/$line/d" $2
            else
            echo "ERROR: $last_name is not in database"
            echo "Would you like to search again (y/n)"
            read delete_choice
            fi
            done
        ;;

So what happens when I execute this code is it brings up the delete message and asks me to input a last name. I put in a last name "smith", when I do this it skips the whole if statement and goes right to the end of the loop and then brings me right up to asking me what the last name is of the person I want to delete. So obviously it is concentrated in the grep statement somewhere. Another odd thing is if I put a name that I know is not in there it will take me to the else statement and give me the error message and ask me if I want to search again.

Any help would be appreciated, I been searching for hours with the grep statement and cannot figure it out.

Additionally: On a side note does anybody know how to make it so I can input "n" or "N" in the Until...Do statement to keep the loop going?

EDIT:

Ok I fixed all the other problems in this code but there is just one problem I cannot fix. Every time I delete an entry from the file it doesn't allow me to execute the echo command.

Code is as follows:

d|D)
            #While loop
            delete_choice="y"       
            while true
            do
                #Create Delete Message
                clear
                echo "                                 Delete Record                                 "
                echo -en '\n'
                echo -en '\n'
                echo "What is the last name of the person you want to delete:"
                read last_name
                if line=$(grep -i "^${last_name}:" "$2")
                then
                    echo "$line" |
                    while IFS=: read c1 c2 rest; do
                        last=$c1
                        first=$c2
                        sed -i "/^$c1:$c2:/d" "$2"
                    done
                    echo -e "Last Name: $last\nFirst Name: $first\nSTUDENT RECORD HAS BEEN DELETED FROM FILE"
                else
                    echo "ERROR: $last_name is not in database"
                    echo "Would you like to search again (y/n):"
                    read delete_choice
                    case $delete_choice in [Nn]) break;; esac
                fi
            done
        ;;

As you can see I execute the echo command but it never displays. However, I can tell that it deletes the entry from the file when I exit the program and check it. Does anybody know how to make it display the echo command correctly?


回答1:


You have used <<< which is a Bash-only feature.

The proper way to debug your problem is to run your script with ksh -x script arg (or possibly sh -x script arg if your script was a pure Bourne shell script; but this one isn't).

However, you have some peculiarities in your code. Allow me to offer a refactoring.

delete_choice="y"           
until [[ "$delete_choice" == "n" ]]
do           # Indent your control structures
    clear
    echo "                                 Delete Record"
    echo # Massive trailing whitespace removed ----------^^^
    echo # Just echo to output a new line
    echo "What is the last name of the person you want to delete:"
    read last_name
    case $last_name in [Nn]) break;; esac      # Exit on "n"
    if line=$(grep -Fi "$last_name" "$2")
    then     # Indent your control structures
        file=$2
        oldIFS=$IFS
        IFS=:
        set -- "$line"   # break input into $1, $2, etc
        IFS=$oldIFS
        echo -e "Last Name: $1\nFirst Name: $2\nI SCREAM IN UPPER CASE"
        sed -i "/^$1:$2:/d" "$file"   # note quoting and -i and changed variable
    else
        echo "ERROR: $last_name is not in database"
        echo "Would you like to search again (y/n)"
        read delete_choice
    fi
done

Another problem here was unrelated to your question. Directly executing the user's input in the regex would be extremely careless -- what if somebody input just a for a last name? The changed code will only delete one user, regardless of how short the input; but perhaps the grep should also be anchored to use a tighter search expression.

There is still a possibility that a peculiar name in the database would not match itself, or match more than itself. For example, I use my second given name, so where my full name is required, I often input my name as "First *Middle Last" with an asterisk next to the name I use, which is the convention where I live; but the string *Middle will not match itself in a regular expression.

Also, without -i, the sed script would simply print a copy of the database to standard output.

The delete_choice variable is not getting updated anywhere within your code so you could change the exterior loop to just while true and handle exiting by breaking out of the loop, like I have done. I didn't change the until on the vague speculation that this might be used in other parts of your code which you aren't showing.



来源:https://stackoverflow.com/questions/28892215/grep-statement-in-if-then-else-statment-is-not-giving-intended-results

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!