我有一个破折号脚本,我需要解析$1
,它是一个包含由 ' :
' 分隔的两个部分的字符串,例如foo:123
.我想保存foo
在 $X 和123
$Y 中。
我想我可以使用read
:
$ echo "foo:123" | tr ':' ' ' | read X Y
但这不起作用(没有给出错误)
$ echo $X
给出空行作为输出。
为什么我的read
构造不起作用?我怎样才能实现我的目标(任何解决方案,不必使用读取)
答案1
在短跑,每个命令管道 在子shell中运行(zsh
以及 AT&T ksh
,管道中最右边的命令没有),因此当您的命令完成时,变量X
和Y
不再存在。
简单地说,您可以使用参数扩展, 尝试:
$ set -- foo:123
$ X=${1%:*}
$ Y=${1#*:}
该示例用于交互式会话。
在您的脚本中,您不需要set -- foo:123
.
答案2
您还可以使用分割+全局运算符(将变量不加引号)(并且您在问题中没有明显原因使用它):
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
您还可以这样做:
printf '%s\n' "$1" | {
IFS=: read -r X Y
printf '%s\n' "$X"
}
就像(但与 AT&T或相反)dash
一样,管道的所有部分都在子 shell 中运行(它们无论如何都需要在不同的进程中运行,因为它们是同时运行的)。上面,我们需要将使用它的部分放在读取和的输出的子 shell 中bash
ksh
zsh
$X
printf
套 $X
。
请注意,如果$1
包含换行符或多个:
字符,这两种解决方案的行为会有所不同。