【问题标题】:Using IFS to split a String into an Array with delimiter in bash使用 IFS 在 bash 中将字符串拆分为带分隔符的数组
【发布时间】:2026-01-03 02:50:02
【问题描述】:

我有一个变量data="password: password@123, url: url@123, username: user@123"。 我正在尝试使用分隔符逗号(,)来拆分它。我想出了以下脚本,它在 CentOS Linux 中运行良好。但在 Debian GNU/Linux 9 (Stretch) 中同样不起作用。

IFS=, read -a array <<< $data
echo ${array[1]}
echo ${array[2]}
echo ${array[3]}

给出输出(CentOS Linux):

password: password@123
url: url@123
username: user@123

但对于 Debian GNU/Linux 9 (Stretch),输出为空。请帮帮我!


编辑: 数据的值是从 JSON 响应中获取的。

data=$(vault kv get -format=json myapp/database | jq '.data' | sed '0,/{/ s/{//' | sed -r 's/(.*)}/\1 /' | sed s/\"//g)
echo $data
password: password@123, url: url@123, username: user@123

vault kv get -format=json myapp/database的回复:

{
  "request_id": "5eee87f9-16dc-fd62-e249-8737a6cd7041",
  "lease_id": "",
  "lease_duration": 2764800,
  "renewable": false,
  "data": {
    "password": "password@123",
    "url": "url@123",
    "username": "user@123"
  },
  "warnings": null
}

解决方案:此脚本适用于 Centos 和 Ubuntu

data=$(vault kv get -format=json myapp/database | jq '.data')
data=$(echo $data | sed 's/ //g' | sed '0,/{/ s/{//' | sed -r 's/(.*)}/\1 /' | sed 's/\"//g')
IFS=, read -a array <<< $data

【问题讨论】:

  • 尝试引用您的变量,data="password: password@123, url: url@123, username: user@123"; IFS=, read -a array &lt;&lt;&lt; "$data"; declare -p arrayprintf '%s\n' "${array[0]}" "${array[1]}" "${array[2]}"
  • 另外,shellcheck.net 是一个很好的 shell 脚本资源。
  • 我无法复制;我在两个平台上都得到了相同的结果(CentOS 8.3.2011);数组元素${array[2]} 为空,但那是因为您使用了错误的索引(第一个元素在${array[0]} 中)。见pastebin.com/KyDSCfYk
  • 如果不是这样,你还能edit 包含在Debian 上使用bash -x 运行脚本的输出吗?
  • 顺便说一句,jq -r ' .data | to_entries[] | "\(.key): \(.value)"' 避免了丑陋的sed 后处理。我怀疑你真的特别想用逗号分开;这会产生换行符分隔的输出。

标签: linux bash centos debian


【解决方案1】:

您问题中的代码不会重现该问题。该问题已正确结束,我们仍然不确定您发布的代码为何不起作用。

但是,正确的解决方法可能是重构您的 jq 命令行以输出您想要的结果,而不是尝试使用一系列凌乱的 sed 命令来修复它。

#!/bin/bash
vault kv get -format=json myapp/database |
jq -r '.data | to_entries[] | "\(.key) \(.value)"')" |
while IFS= read -r key value; do
    printf -v "$key" %s "$value"
done

如果您的 Bash 足够新 (5+),也许更好的设计是将这些读入关联数组。

#!/bin/bash
declare -A config
vault kv get -format=json myapp/database |
jq -r '.data | to_entries[] | "\(.key) \(.value)"')" |
while IFS= read -r key value; do
    config["$key"]="$value"
done

也许有一些方法可以让vault kv get 将其输出格式化为更适合在 shell 脚本中使用的格式。

(切线,几乎任何看起来像sed 's/a/b/' | sed 's/x/y/g' 的东西最好重构为sed 's/a/b/;s/x/y/g'。另见Combining two sed commands

【讨论】:

  • vaultproject.io/docs/commands/kv/get 建议其默认输出格式可能更适合您尝试执行的操作。如果你的消费者理解 JSON,JSON 就可以了,但 Bash 不理解,所以你只是把事情复杂化了。
最近更新 更多