我有一个变量长得像这样:
msg="newton apple tree"
我想将这些单词分别赋值给不同的变量。在Bash中,这很容易实现:
read a b c <<< $msg
在 POSIX shell 中,有没有一种紧凑易读的方法来完成这个任务?
一个Here字符串只是单行Here文档的一种语法糖:
$ msg="foo * bar"
$ read a b c <<EOF
> $msg
> EOF
$ echo "$a"
foo
$ echo "$b"
*
$ echo "$c"
bar
echo "$a"
的输出。其他行被省略了。例如,echo "$b"
为空。 - t7eread
只读取其中一行。如果你想从 here-string 中读取三行,你需要三个单独的 read
命令,例如 { read a; read b; read c; } <<< "$FOO"
。 - chepner要撰写通顺的脚本,不能仅仅查看每个语法单元并尝试找到与 POSIX 相对应的等效项。这就像通过用字典中每个单词的条目替换每个单词来翻译文本。
将已知有三个单词的字符串拆分为三个参数的 POSIX 方式类似但不完全相同于 read
:
var="newton apple tree"
set -f
set -- $var
set +f
a=$1 b=$2 c=$3
echo "$a was hit by an $b under a $c"
$@
,但这是一个很好的解决方案。 - Charles Duffyset
命令替换read
。 - chepnermkfifo mypipe
printf '%s\n' "$msg" >mypipe &
read -r a b c <mypipe
printf
比echo
更可靠/规范; 如果您有一个仅包含-E
或-n
的消息,echo
的行为会因实现而异。
话虽如此,针对你在这里所做的事情,你可以只使用参数扩展:
a=${msg%% *}; msg=${msg#* }
b=${msg%% *}; msg=${msg#* }
c=${msg%% *}; msg=${msg#* }
echo "$msg" | { read a b c; do_something_with "$a"; }
,但是当管道关闭时,这些值仍然未设置。 - Charles Duffy