【问题标题】:Split a paragraph into lines in ZSH在 ZSH 中将段落拆分为行
【发布时间】:2010-06-29 15:51:51
【问题描述】:

如何在 zsh 中获取多行字符串,并将其拆分为一个字符串数组,每个字符串为一行?

具体来说我想取cal的输出

      June 2010     
Su Mo Tu We Th Fr Sa
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

把它变成

("      June 2010     " "Su Mo Tu We Th Fr Sa" "       1  2  3  4  5"  " 6  7  8  9 10 11 12" "13 14 15 16 17 18 19" "20 21 22 23 24 25 26" "27 28 29 30")

这是一个 zsh 数组。


然后我的最终目标是获取另一个命令的输出并将它们并排放置,所以如果我有

a
b
c

d
e
f

我最终会得到

a d
b e
c f

【问题讨论】:

    标签: string shell zsh


    【解决方案1】:

    在 zsh 中,你可以输入

    array=( ${(s.
    .)"$(cal)"} )
    

    或者,使用 eval:

    eval $'array=( ${(s.\n.)"$(cal)"} )'
    

    这里(s.smth.) 指定要拆分的表达式(没有模式,只有固定的字符串。与 IFS 不同,(s.:::.) 将在 ::: 上拆分,而IFS=':::' 将在 : 上拆分)。 eval 用于将换行符放入(s) 标志内,因为(s.\n.) 表示在反斜杠上拆分,后跟字母«n»。

    【讨论】:

    • 或者只是${(f)"$(cal)"}fps:\n: 相同。后者还展示了如何在不诉诸eval 的情况下使用s 的“转义”。
    • 你的第一个对我不起作用(我把所有东西都放在一个数组元素中),除非我引用命令替换:"$(cat)" 就像 Chris 在上面的评论。
    • @Chris Johnsen 谢谢,忘记了p 并且不知道引用。也许您应该发布自己的答案?
    • 呃,我的意思是"$(cal)",但你明白了。
    【解决方案2】:

    这是一个可以在 zsh 和 Bash 中使用的进程替换示例。它使用 Unix/Linux 工具 paste 将两个日历并排放置作为演示。

    $ paste <(cal 6 2009) <(cal 6 2010)
    
         June 2009               June 2010
    Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa
        1  2  3  4  5  6           1  2  3  4  5
     7  8  9 10 11 12 13     6  7  8  9 10 11 12
    14 15 16 17 18 19 20    13 14 15 16 17 18 19
    21 22 23 24 25 26 27    20 21 22 23 24 25 26
    28 29 30                27 28 29 30
    

    直接回答您的问题:

    saveIFS=$IFS; IFS=$'\n'; array=($(cal 6 2010)); IFS=$saveIFS
    

    这也适用于 Bash。

    【讨论】:

    • 第二个分号可以省略。
    • 其实保存和恢复IFS也是:IFS=$'\n' array=($(cal 6 2010))
    • @rocky:不,作业不是这样工作的。如果您测试您发布的内容,您会看到IFS 没有恢复。这适用于“简单命令”,例如IFS=$'\n' read -r var.
    猜你喜欢
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多