【问题标题】:Split string with zsh as in Python使用 zsh 分割字符串,就像在 Python 中一样
【发布时间】:2010-05-28 15:21:54
【问题描述】:

在python中:

s = '1::3'
a = s.split(':')
print a[0] # '1' good
print a[1] # '' good
print a[2] # '3' good

如何使用zsh达到同样的效果?

以下尝试失败:

string="1::3"
a=(${(s/:/)string})
echo $a[1] # 1
echo $a[2] # 3 ?? I want an empty string, as in Python

【问题讨论】:

    标签: string split zsh


    【解决方案1】:

    解决方法是使用@修饰符,如the zsh docs所示:

    string="1::3"
    a=("${(@s/:/)string}") # @ modifier
    

    顺便说一句,如果可以选择分隔符,那么使用换行符作为分隔符会更容易且不易出错。那么用 zsh 分割行的正确方法是:

    a=("${(f)string}")
    

    我不知道这里是否也需要引号......

    【讨论】:

    • 谢谢。你能解释一下它是如何工作的吗,这么多括号让人困惑!
    • 如果你想用斜线分割,原来的/s 可以替换为|s,看起来(例如a=(${(s|/|)string}"))。不过,我似乎找不到任何关于此的文档,所以也许有一些微妙的行为变化。
    • @Harry,链接的文档这样说:“任何字符,或匹配对 '(...)'、'{...}'、'[...]' 或'<...>',可以用来代替冒号作为分隔符,......”在 Olivier 的代码中,“用于代替冒号”的字符是斜杠;在你的,它是垂直条。所以,没有行为改变。
    • 这在命令行中可以正常工作,但是当我将它移到一个函数中时,我得到了“无法识别的修饰符”错误,你知道吗?
    • 比 IFS bash 等价物更容易理解。谢谢
    【解决方案2】:

    这适用于 zsh(使用 setopt shwordsplit 或 zsh -y)和 Bash(从零开始的数组):

    s="1::3"
    saveIFS="$IFS"
    IFS=':'
    a=(${s})
    IFS="$saveIFS"
    

    【讨论】:

    • 这在命令行上对我有用,但在函数中对我不起作用,即使我确保设置了 shwordsplit。我不知道为什么没有。
    • @ws_e_c421:它适用于 zsh 和 Bash 中的函数。你没有说你用的是哪个。您应该能够分别echo ${a[1]} 和echo ${a[3]} 并获得1 和3(对于Bash,下标应该是0 和2)。如果它很短,请在此处发布您尝试过的内容以及失败的原因。如果有点长,请在此处发布一个新问题并链接到它。
    • 恕我直言,您应该像这样对环境变量进行范围更改,例如IFS=':' cmd args...,因此更改与预期/使用的上下文/寿命相结合。那么,了解您没有使用的先前值,或者管理或重建外部环境等就不是您的工作了 - 相反,它们会自行清理。
    • @JohnP:这种作用域不适用于变量赋值(在这种情况下,从标量创建数组)。另一种使用子shell 的作用域在这里不起作用,因为正在创建的数组也将作用于子shell,因此以后不可用。但是你的观点在有用的情况下是有效的。
    • @JohnP:对我有用。这是我从函数内部的回显中看到的输出(添加了缺少的分号):1, 1::3, ':'。 1 是数组a 的第一个元素,它是拆分s 的结果。有关输出数组的更好方法,请参阅我早期的 cmets。我之前没有提到的是在函数中使用local IFS=':' 来限制范围(但这不适用于您的原始观点)。
    猜你喜欢
    • 2013-03-30
    • 2017-04-12
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 2012-02-14
    • 2021-12-03
    • 2021-06-12
    相关资源
    最近更新 更多