将CSV字符串分割成适用于bash和zsh的数组的最简单方法

3
仅使用内置函数,最简单的方法将CSV字符串拆分为数组并能在Bash和Zsh中运行是什么?我有两个不同的可在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

1
为避免未引用的扩展,Bash 方法应该是 IFS=, read -a array <<< "$csv" - 不确定在 zsh 中是否适用。 - Benjamin W.
3
zsh 中,它将是 IFS=, read -rA arr <<< "$csv" - anubhava
1
噢,好吧 - 无论如何,Bash 版本应该仍然是这样的 ;) - Benjamin W.
@XDR:为什么要编写能在两种非常不同的编程语言中工作的代码?您的代码很可能驻留在脚本中,并通过 #! 行指定是 bash 还是 zsh,也就是说,它不会被源引用,对吗?我不认为强制程序能够在两个 shell 上运行有任何意义。 - user1934428
它将被源化。现有的代码与bash和zsh兼容,因此我必须保持其兼容性。这不是我的决定。 - XDR
1个回答

7

正如评论中所指出的那样,有两个几乎相同的命令,每个 shell 都有一个。

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

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

语法相同;唯一的区别在于您使用aA作为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"

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


1
IFS=,read -r"${BASH_VERSION:+a}${ZSH_VERSION:+A}" array <<< "$csv"::D - KamilCuk
没错 :) 但我更愿意将嗅探逻辑与业务逻辑分开。可能还有其他特定于 shell 的差异需要考虑,这些都可以在脚本开头的单个 if 语句中设置。 - chepner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接