我正在写一个shell脚本,在该脚本中,用户应输入一个字符串(后接enter),并且有些字符会立即终止“ read”命令。我做了研究发现:
read -d '.'
因此,这意味着读命令将在'。'时终止。输入。所以我可以输入
Hello, this is the user's input.
输入点后,“读取”将终止。
但是我需要使用不同的定界符。我需要一种方法来使``读取''在例如用户输入“ E”或“ e”。 我用通配符尝试过:
read -d [E,e]
,但是'['是终止定界符。 'read'忽略'E'和'e',但在输入'['时终止。
我还尝试了几个“ -d”标志:
read -d 'E' -d 'e'
但是似乎第二个'-d'覆盖了第一个。只是'e'是标记作为终止定界符,'E'被忽略。
我该怎么办? “读取”或其他命令还有其他可能性吗?
答案 0 :(得分:1)
string=''
store_IFS="$IFS" # Storing current IFS value
IFS= # Setting IFS to Null to space characters to enter
while true
do
read -sn 1 k # -n for reading byte by byte and -s is to suppress the printing of input.
if [ "$k" = $'\177' ] && [ -n "$string" ] # Check whether it is backspace and string is not empty
then
printf %b "\b \b" # '\b' moves the cursor 1 unit left and then printing '\b' then again moves the cursor left so that it looks like a character erased :)
string=${string::-1} # Now remove the last character from the string
continue
fi
# Now check for each delimiter you want.
case $k in
[Ee])
break
;;
esac
# Now Concatenate that byte with the previous input string
string+=$k
printf '%s' "$k" # Now print the current inputted char
done
IFS="$store_IFS" # Restoring IFS value
printf '\n%s\n' "Your string -> $string"
我不知道是否有内置命令可以执行此操作,但是您可以使用上面的bash代码轻松实现它。
修改
修正了注释中建议的代码错误
答案 1 :(得分:0)
这里有一个kluudgey函数,它一次读取一个char,如果不是第一个参数中传递的终止符,则将每个char打印到 STDERR (供用户反馈)和 STDOUT < / em>(分配给变量):
readdelim() { n=["$1"']{1}'
while read -s -N 1 v ; do
[[ "$v" =~ $n ]] && break
printf "$v" | tee /dev/stderr
done
echo > /dev/stderr; }
像这样使用它:
n=$(readdelim eE) ; echo $n
...并输入“ ba bat bate” 之类的内容,$n
的内容将为“ ba bat bat” 。