使用两个定界符之一终止读取(即,读取-d'。'->读取-d'[Ee]')

时间:2019-01-06 11:23:07

标签: bash shell

我正在写一个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'被忽略。

我该怎么办? “读取”或其他命令还有其他可能性吗?

2 个答案:

答案 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”

>