【问题标题】:Simplest way to split a csv string into an array that works for both bash & zsh将 csv 字符串拆分为适用于 bash 和 zsh 的数组的最简单方法
【发布时间】:2020-06-29 22:44:56
【问题描述】:

仅使用适用于 bash 和 zsh 的内置函数将 csv 字符串拆分为数组的最简单方法是什么?

我有单独的代码适用于 bash 和 zsh,但我还没有找到任何适用于两者的代码:

csv='a,b,c'

# Works in zsh, but not in bash
array=(${(s:,:)csv})

# Works in bash, but not in zsh
array=(${csv//,/ }) # This requires that $IFS contains the space character

【问题讨论】:

  • 为了避免不加引号的扩展,Bash 方法应该是IFS=, read -a array <<< "$csv"——不知道这是否适用于 zsh。
  • zsh 中是IFS=, read -rA arr <<< "$csv"
  • 啊,好吧——无论如何,对于 Bash 版本应该仍然如此;)
  • @XDR :你为什么要编写对两种完全不同的编程语言工作相同的代码?您的代码很可能驻留在脚本中,该脚本(通过 #! 行)指定它是 bash 还是 zsh,即它不会被获取,不是吗?我看不出强制程序能够在两个 shell 上运行的意义。
  • 它将被采购。现有代码与 bash 和 zsh 都兼容,所以我必须保持兼容。这不是我的决定。

标签: arrays string bash split zsh


【解决方案1】:

正如 cmets 中所指出的,有两个几乎相同的命令,每个 shell 一个。

# bash
IFS=, read -ra array <<< "$csv"

# zsh
IFS=, read -rA array <<< "$csv"

语法相同;唯一的区别是您是使用a 还是A 作为read 的选项。我建议添加一个条件语句来检测哪个 shell 正在执行脚本,然后使用变量来存储正确的选项。

if [ -n "$BASH_VERSION" ]; then
    arr_opt=a
elif [ -n "$ZSH_VERSION" ]; then
    arr_opt=A
fi

IFS=, read -r"$arr_opt" array <<< "$csv"

检查非空版本参数并非万无一失,但应该足够好了。

【讨论】:

  • IFS=, read -r"${BASH_VERSION:+a}${ZSH_VERSION:+A}" array &lt;&lt;&lt; "$csv":D
  • True :) 但我宁愿将嗅探逻辑与业务逻辑分开。您可能需要考虑其他特定于 shell 的差异,这些差异都可以在脚本开头的单个 if 语句中设置。
猜你喜欢
  • 2017-01-08
  • 1970-01-01
  • 2011-10-18
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多