问题描述
该计划的预期结果是通过搜索姓氏来从临时文件中删除记录。如果名称在文件中,则会显示一条消息,指出该文件已被删除。该消息将具有被删除人员的姓氏和名字。如果输入的名称没有记录,则显示一条错误消息,指出名称不在文件中。错误消息将会包含搜索到的人的姓氏。
大部分情况下,我已经完全将这些代码弄清楚了。然而,我遇到的错误给我带来了很多麻烦。
代码如下:
#While循环
delete_choice =y
直到[[$ delete_choice ==n]]
do
#Create Delete消息
清除
echo删除记录
echo -en'\\\
'
echo -en'\\\
'
echo什么是姓氏
读取姓氏
如果行= $(grep -Fi$ last_name$ 2)
然后
IFS =:读取c1 c2休息 echo -e姓:$ c1 \ nFirst名称:$ c2 \暂停记录已从文件中删除
sed/ $ line / d$ 2
else
echoERROR:$ last_name不在数据库中
echo你想再次搜索(y / n)
读取delete_choice
fi
完成
;;
那么当我执行这段代码时会发生什么呢?它会显示删除消息并要求我输入姓。我输入姓氏史密斯,当我这样做时,它跳过整个if语句并且直接到循环结尾,然后让我直接问我什么是我想删除的人的姓氏。所以显然它集中在某处的grep语句中。另一个奇怪的是,如果我把一个我知道不在那里的名字带到我的else语句中,并给我错误信息,并询问我是否要再次搜索。
任何帮助,将不胜感激,我一直在寻找与grep声明小时,并不能解决它。
另外:在一个侧面说明有人知道如何做到这一点,我可以在Until ... Do语句中输入n或N来保持循环?
编辑:
好的,我修复了这段代码中的所有其他问题,但只有一个问题我无法修复。每次我从文件中删除一个条目时,都不允许执行echo命令。
代码如下:
d | D)
#While循环
delete_choice =y
而真
#Create Delete Message
clear
echoDelete Record
echo -en'\\\
'
echo -en'\\\
'
echo什么是
读取姓氏
if line = $(grep -i^ $ {last_name}:$ 2)
然后
回显$ line|
,而IFS =:读取c1 c2 rest;做
last = $ c1
first = $ c2
sed -i/ ^ $ c1:$ c2:/ d$ 2
完成
echo - e姓氏:$ last \ nFirst名称:$ first \暂停记录已从文件中删除
else else $ b $ echo错误:$ last_name不在数据库中
echo你想再次搜索(y / n):
read delete_choice
case $ delete_choice in [Nn])break ;; esac
fi
完成
;;
正如您所看到的,我执行echo命令,但它永远不会显示。但是,我可以告诉它在退出程序并检查它时删除文件中的条目。是否有人知道如何正确显示echo命令?
您已使用<< ;< 这是一个仅限Bash的功能。
调试问题的正确方法是使用<$ c $如果你的脚本是一个纯粹的Bourne shell脚本,那么c> ksh -x脚本arg (或者可能是 sh -x script arg ;但是这个脚本不是' t)。
然而,你的代码中有一些特性。
delete_choice =y
直到[[$ delete_choice== n]]
do#缩进控制结构
清除
回显删除记录
回显#删除大量尾随空格---------- ^^ ^
echo#只是回声输出一个新行
echo你想删除的人的姓氏是什么:
读取姓氏
case $ last_name in [Nn ])break ;; esac#退出n
if line = $(grep -Fi$ last_name$ 2)
then#缩进控制结构
file = $ 2
oldIFS = $ IFS
IFS =:
set - $ line#break输入到$ 1,$ 2等
IFS = $ oldIFS
echo -eLast Name:$ 1 \\ \\ n第一个名称:$ 2 \\\
I SCREAM IN UPPER CASE
sed -i/ ^ $ 1:$ 2:/ d$ file#注意引号和-i并更改变量
其他
echoERROR:$ last_name不在数据库中
echo你想再次搜索(y / n)
读取delete_choice
fi
完成
这里的另一个问题与您的问题无关。直接在正则表达式中执行用户的输入将会非常不小心 - 如果某人输入了 a 作为姓,该怎么办?无论输入有多短,更改后的代码只会删除一个用户;但也许还应该使用 grep 来使用更紧密的搜索表达式。
仍有可能数据库中的特殊名称本身不匹配,或比自身匹配更多。例如,我使用我的第二个给定名称,所以在需要我的全名的情况下,我经常在我使用的名称旁边输入我的名字作为First * Middle Last,旁边是星号,这是我生活的惯例;但是字符串 * Middle 在正则表达式中不会匹配。
另外,如果没有 -i , sed 脚本只会将数据库的副本打印到标准输出中。
delete_choice 变量在代码中的任何地方都没有得到更新,因此您可以将外部循环更改为,而true 并通过跳出循环来处理退出,就像我所做的那样。我没有更改直到,因为这个模糊的猜测可能会在您没有显示的代码的其他部分使用。
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?
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.
这篇关于Grep声明在If-Then-Else Statment中没有给出预期的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!