Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: read options to slurp empty lines ?

On Fri, Jun 1, 2018 at 2:47 PM, Marc Chantreux <eiro@xxxxxxxxx> wrote:
> i use to have slurp function made like this
> slurp     () IFS=$'\n' read -r -d ' -A $1

I presume that to be a typo or cut-and-paste error because you have an
unmatched single quote there.

> i recently saw that
>     print -l '' bar bang '' | slurp them
>     # got them=( bar bang )
>     # expected them=( '' bar bang '' )

For the confused or those with proportional fonts, '' above is two
single quotes, not a double quote, so there should be four lines
output by "print -l".

I get

% typeset -p them
typeset -a them=( bar bang '' )

The behavior of "read" is to collapse multiple consecutive occurrences
of $IFS characters into a single one.  Because an empty string
followed by a newline looks like nothing more than a newline, all
those lines collapse.  [The single empty element I got at the end is
there not because there were trailing empty lines, but because end of
input was reached without finding the delimiter (this is not standard
so probably ought to be controlled by POSIX_BUILTINS or something).]
So for example:

% print -l x '' '' '' bing bong '' '' '' y | slurp
% typeset -p reply
typeset -a reply=( x bing bong y '' )

Same thing happens in e.g. bash (except without the final empty
element, see above).

> i tried to patch it using some read options ... did i miss something using read builtin ?

Only that there's no simple way to make it do what you want. :-)

You're probably looking for this:

slurp() {
  local REPLY
  IFS= read -d '' &&
  set -A ${1:-reply} "${(@f)REPLY}"

Messages sorted by: Reverse Date, Date, Thread, Author