
Question:
How can I take a multi-line string in zsh, and split it into an array of strings that are a single line each?
Specifically I want to take the output of 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
and turn it into
(" 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")
Which is a zsh array.
My ultimate goal is then to take the output of another command and put them side by side, so if i had
a b c
and
d e f
I would end up with
a d b e c f
Solution:1
Here's an example of process substitution which will work in zsh and Bash. It uses the Unix/Linux tool paste
to put two calendars side-by-side as a demonstration.
$ 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
To answer your question directly:
saveIFS=$IFS; IFS=$'\n'; array=($(cal 6 2010)); IFS=$saveIFS
Which also works in Bash.
Solution:2
In zsh, you may type
array=( ${(s. .)"$(cal)"} )
or, with eval:
eval $'array=( ${(s.\n.)"$(cal)"} )'
Here (s.smth.)
specifies the expression to split on (no patterns, only fixed string. Unlike IFS, (s.:::.)
will split on :::
, while IFS=':::'
will split on :
). eval
is used in order to put newline character inside (s)
flag since (s.\n.)
means split on backslash followed by letter «n».
Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
EmoticonEmoticon