Tutorial :Split a paragraph into lines in ZSH



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
Previous
Next Post »