如何从 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 =)
我正在尝试拆分键值对(围绕 = 符号),然后使用 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
.
$ 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 =)