我遇到以下代码的问题:
IFS=: read c1 c2 c3 c4 rest <<< "$line"
不要错误地认为这段代码运行良好,但它似乎并没有用于ksh。我基本上需要在没有&#34;&lt;&lt;&lt;&#34;的情况下编写相同的代码。关于&#34;&lt;&lt;&lt;&#34;的信息不多。线上。如果有人有任何想法,将非常感激。
修改
编程的整个部分的代码如下:
m|M)
#Create Modify Message
clear
echo " Modify Record "
echo -en '\n'
echo -en '\n'
while true
do
echo "What is the last name of the person you would like to modify:"
read last_name
if line=$(grep -i "^${last_name}:" "$2")
then
oldIFS=$IFS
IFS=:
set -- $line
IFS=$oldIFS
c1=$1
c2=$2
c3=$3
c4=$4
shift; shift; shift; shift
rest="$*"
echo -e "Last Name: $1\nFirst Name: $2\nState: $4"
while true
do
echo "What would you like to change the state to?:"
read state
if echo $state | egrep -q '^[A-Z]{2}$'
then
echo "State: $state"
echo "This is a valid input"
break
else
echo "Not a valid input:"
fi
done
echo -e "Last Name: $c1\nFirst Name: $c2\nState: $state"
echo "State value changed"
break
else
echo "ERROR: $last_name is not in database"
echo "Would you like to search again (y/n):"
read modify_choice
case $modify_choice in [Nn]) break;; esac
fi
done
;;
好的,除了
外,一切正常echo -e "Last Name: $c1\nFirst Name: $c2\nState: $state"
它只会显示:
姓氏:
名字:
州:
所以我可以看到它没有正确地将它添加到我的回声中。
最终编辑
CODE:
#Case statement for modifying an entry
m|M)
#Create Modify Message
clear
echo " Modify Record "
echo -en '\n'
echo -en '\n'
while true
do
echo "What is the last name of the person you would like to modify:"
read last_name
if line=$(grep -i "^${last_name}:" "$2")
then
echo "$line" |
while IFS=: read c1 c2 c3 c4 rest; do
echo -e "Last Name: $c1\nFirst Name: $c2\nState: $c4"
last=$c1
first=$c2
done
while true
do
echo "What would you like to change the state to?:"
read state
if echo $state | egrep -q '^[A-Z]{2}$'
then
echo "State: $state"
echo "This is a valid input"
break
else
echo "Not a valid input:"
fi
done
echo -e "Last Name: $last\nFirst Name: $first\nState: $state"
echo "State value changed"
break
else
echo "ERROR: $last_name is not in database"
echo "Would you like to search again (y/n):"
read modify_choice
case $modify_choice in [Nn]) break;; esac
fi
done
;;
答案 0 :(得分:3)
Bash中的here string
command <<<"string"
基本等同于
echo "string" | command
明显的例外是后者使用管道,这意味着你无法有意义地将它与read
一起使用。常见的解决方法是使用set
内置函数从字符串或外部命令中捕获令牌:
oldIFS=$IFS
IFS=:
set -- $line # no quotes
IFS=$oldIFS
c1=$1
c2=$2
c3=$3
c4=$4
shift; shift; shift; shift
rest="$*" # loses spacing / quoting
另一种解决方法是使用循环,只迭代一次;这看起来似乎很优雅,但如果伪循环的主体很长或很复杂,可能会导致相当笨重的代码。
echo "$line" |
while IFS=: read c1 c2 c3 c4 rest; do
: stuff which uses those variables
done
这解决了echo stuff | read variable
在子进程中运行read
并因此立即忘记variable
的值的问题 - while
循环的正文是read
发生的所有相同过程,因此初始化的变量值在循环内可见。
另一种类似的解决方法是将read和procesIn委托给一个函数;
process () {
IFS=: read c1 c2 c3 c4 rest
: stuff which uses those variables
}
echo "$line" | process
这是笨重还是优雅取决于功能中发生的事情。如果它整齐地封装,它可能是相当有吸引力的;但如果你最终传递了一堆不相关的变量(或者更糟糕的是,修改函数内部的全局变量!)它可能恰恰相反。