我有一个破折号脚本,我需要解析$1
,它是一个包含由 ' :
'分隔的两部分的字符串,例如foo:123
. 我想存入foo
$X 和123
$Y。
我以为我可以使用read
:
$ echo "foo:123" | tr ':' ' ' | read X Y
Run Code Online (Sandbox Code Playgroud)
但这不起作用(没有给出错误)
$ echo $X
Run Code Online (Sandbox Code Playgroud)
给出空行作为输出。
为什么我的read
构造不起作用?我怎样才能实现我的目标(任何解决方案,都不必使用读取)
在dash 中,管道中的 每个命令都在子shell中运行(zsh
而 AT&T ksh
,管道中最右边的命令不是),因此当您的命令完成时,变量X
和Y
不再存在。
简单地说,您可以使用Parameter Expansion,尝试:
$ set -- foo:123
$ X=${1%:*}
$ Y=${1#*:}
Run Code Online (Sandbox Code Playgroud)
该示例用于交互式会话。
在您的脚本中,您不需要set -- foo:123
.
您还可以使用split+glob运算符(将变量不加引号)(并且您在问题中没有明显原因使用它):
IFS=: # configure the split part to use : as the delimiter
set -f # disable the glob part
set -- $1 # $1 is split on : and parts are stored in $1, $2...
X=$1 Y=$2
Run Code Online (Sandbox Code Playgroud)
您还可以这样做:
printf '%s\n' "$1" | {
IFS=: read -r X Y
printf '%s\n' "$X"
}
Run Code Online (Sandbox Code Playgroud)
就像(但与 AT&T或相反)dash
一样,管道的所有部分都在子 shell 中运行(它们无论如何都需要在不同的进程中运行,因为它们是同时运行的)。上面,我们需要将使用它的部分放在读取和设置的输出的子 shell 中。bash
ksh
zsh
$X
printf
$X
$1
请注意,如果包含换行符或多个字符,这两种解决方案的行为会有所不同:
。