如何从 shell-redirect 或 `read` 拆分字符串?

How do you split a string from shell-redirect or `read`?

我正在尝试拆分键值对(围绕 = 符号),然后使用 bash 将其用于编辑配置文件。但是我需要 IFS 的 <<< 语法的替代方法。

以下适用于我的 host 系统,但是当我通过 ssh 登录到我的 ubuntu 虚拟 machine 时,我有错误的 bash 版本.无论我尝试什么,<<< 都会失败。 (我肯定是在文件顶部调用正确版本的 bash,使用 #!/bin/bash(我也尝试过 #!/bin/sh 等))。

我知道我可以在我的 host mac os x 系统上使用 IFS,如下所示:

var="word=hello"        
IFS='=' read -a array <<<"$var"
echo ${array[0]} ${array[1]]}

#alternative -for calling through e.g. sh file.sh param=value
for var in "$@"
    do      
    IFS='=' read -a array <<<"$var"
    echo ${array[0]} ${array[1]]}
done


#alternative
  IFS='=' read -ra array <<< "a=b"
  declare -p array
  echo ${array[0]} ${array[1]}

但这在我的虚拟机上不起作用。

我也知道我应该能够通过反引号 $()echo "$var" | ... 切换 <<< 语法,但我无法让它工作 - 如下:

#Fails
    IFS='=' read -ra myarray -d '' <"$var"
    echo ${array[0]} ${array[1]]}

#Fails
    echo "$var" | IFS='=' read -a array
    echo ${array[0]} ${array[1]]}

#fails
echo "a=b" | IFS='=' read -a array
declare -p array
echo ${array[0]} ${array[1]}

感谢任何指点,因为我对 bash 真的很陌生。

您第一次尝试失败是因为 <<<< 是不同的运算符。 < 打开命名文件。

第二个失败,因为read只在管道启动的subshell中设置了array的值; shell 在管道完成后退出,array 随之消失。

第三个失败的原因与第二个相同;接下来的 declare 没有任何区别。

您的尝试被混淆了,因为您必须在与 read.

相同的子shell 中使用变量
$ echo 'foo=bar' | { IFS='=' read -a array; echo ${array[0]}; }
foo

并且如果您希望您的变量持久化(即,在子 shell 范围之外):

$ var=$(echo 'foo=bar' | { IFS='=' read -a array; echo ${array[0]}; })
$ echo $var
foo

显然,它并不漂亮。


更新: 如果缺少 -a,则表明您已脱离数组领域。您可以尝试参数替换:

str='foo=bar'
var=${str%=*}
val=${str#*=}

如果这不起作用,请回退到好的 ole 剪辑:

str='foo=bar'
var=$(echo $str | cut -f 1 -d =)
val=$(echo $str | cut -f 2 -d =)