Reputation: 3048
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
Upvotes: 3
Views: 4043
Reputation: 53614
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».
Upvotes: 7
Reputation: 360035
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.
Upvotes: 6